问题:

我目前在使用Swift开发使用以下内容的iOS移动应用程序时遇到问题:


BTLE:连接到外围设备并向/从该外围设备发送/接收数据。
Networking:如果外围设备连接到网络(无线和/或以太网),则通过BTLE的通信“可以”通过网络进行。
Model-View-ViewModel体系结构
RxSwift


关于应用程序:

它从“蓝牙设置”视图开始,该视图将引导用户完成与外围设备配对的过程(与TabBarController不相交)。

与设备成功配对后,iOS App从设备请求所有配置,并以JSON的形式发送。

JSON包含应用显示给用户的不同Model信息(编程),以便进行操作,并且需要以某种方式存储在Singleton庄园中的数组中,view-model可以请求任何索引来显示给用户。

接收完所有数据后,蓝牙视图关闭,并显示TabBarView。

当前示例:

与此应用程序相关的一个很好的例子是Apple Watch和相关的iOS应用程序,它允许您配置所有内容。我必须做一些相同的概念。

这个blog post中的另一个很好的示例应用程序,在这些应用程序中,它们正在执行与我要实现的目标类似的操作。不过,我遇到的区别是它们为MVVM进行的依赖项注入设置(以及其他类似示例)。我使用了情节提要,因为他们以编程方式实例化了AppDelegate中的视图控制器。

还有我的问题

如何在没有NSNotificationsPrepareForSegues的情况下将数据从BluetoothView有效地传递到TabBarView?请记住,我打算将库RxSwift用于异步事件处理和事件/数据流。我正在尝试使该应用尽可能无状态。

blog post中的Servers是否是检索和/或更新它们的好习惯?

最佳答案

我发现,使用RxSwift时,“视图模型”最终成为单个纯函数,该函数从输入UI参数中获取可观察参数,然后返回可观察值,然后将其与输出UI元素绑定。

tutorial videos for cycle.js确实可以帮助我绕过Rx。

至于你的难题

您正在做的事情不必是“前进”运动。这样看吧... TabBarView需要一些数据,并且不在乎这些数据来自何处。因此,使TabBarView可以访问返回包含所需数据的Observable的函数。该关闭将显示Bluetooth View,建立连接,获取必要的数据,然后关闭Bluetooth View并使用所需的数据调用onNext

查看this gist可能有助于了解我在说什么。授予要点使用PromiseKit而不是RxSwift,但是可以使用相同的原理(而不是fulfill,您先要先调用onNext,然后再调用onCompletion。)在要点中,仅需要数据的视图控制器调用一个函数并订阅结果(在这种情况下,结果包含一个UIImage。)函数的工作是确定可用的图像源,询问用户他们要从哪个源中检索图像并提供适当的视图控制器以获取图像。

要点的当前内容如下:

//
//  UIViewController+GetImage.swift
//
//  Created by Daniel Tartaglia on 4/25/16.
//  Copyright © 2016 MIT License
//

import UIKit
import PromiseKit


enum ImagePickerError: ErrorType {
    case UserCanceled
}

extension UIViewController {

    func getImage(focusView view: UIView) -> Promise<UIImage> {
        let proxy = ImagePickerProxy()
        let cameraAction: UIAlertAction? = !UIImagePickerController.isSourceTypeAvailable(.Camera) ? nil : UIAlertAction(title: "Camera", style: .Default) { _ in
            let controller = UIImagePickerController()
            controller.delegate = proxy
            controller.allowsEditing = true
            controller.sourceType = .Camera
            self.presentViewController(controller, animated: true, completion: nil)
        }
        let photobinAction: UIAlertAction? = !UIImagePickerController.isSourceTypeAvailable(.PhotoLibrary) ? nil : UIAlertAction(title: "Photos", style: .Default) { _ in
            let controller = UIImagePickerController()
            controller.delegate = proxy
            controller.allowsEditing = false
            controller.sourceType = .PhotoLibrary
            self.presentViewController(controller, animated: true, completion: nil)
        }
        let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)

        let alert = UIAlertController(title: nil, message: nil, preferredStyle: .ActionSheet)
        if let cameraAction = cameraAction {
            alert.addAction(cameraAction)
        }
        if let photobinAction = photobinAction {
            alert.addAction(photobinAction)
        }
        alert.addAction(cancelAction)
        let popoverPresentationController = alert.popoverPresentationController
        popoverPresentationController?.sourceView = view
        popoverPresentationController?.sourceRect = view.bounds
        presentViewController(alert, animated: true, completion: nil)
        let promise = proxy.promise
        return promise.always {
            self.dismissViewControllerAnimated(true, completion: nil)
            proxy.retainCycle = nil
        }
    }
}


private final class ImagePickerProxy: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    let (promise, fulfill, reject) = Promise<UIImage>.pendingPromise()
    var retainCycle: ImagePickerProxy?

    required override init() {
        super.init()
        retainCycle = self
    }

    @objc func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
        let image = (info[UIImagePickerControllerEditedImage] as? UIImage) ?? (info[UIImagePickerControllerOriginalImage] as! UIImage)
        fulfill(image)
    }

    @objc func imagePickerControllerDidCancel(picker: UIImagePickerController) {
        reject(ImagePickerError.UserCanceled)
    }
}

关于ios - 实现MVVM,网络和蓝牙的iOS App体系结构如何?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37491547/

10-11 22:49
查看更多