我正在我的项目中使用MVVM模式实现RAC,现在我遇到了疑问。 我有很多调用服务器,但它们都与UIButton相关联并在我的ViewModel中处理;现在我需要在加载UIViewController时调用服务器。在MVVM之前,我刚刚在viewDidLoad方法中创建了一个voilá!的信号,但我不确定是否可以将它放在ViewController中。 现在我不知道如何将RACSignal绑定到我的ViewController中的事件,最糟糕的是,我不确定这是否遵循MVVM模式。
当我通过用户操作(来自UIButton)调用服务器时,我正在做的是:
的ViewController *
self.someButton.rac_command = viewModel.executeSomeAction
//On success:
self.viewModel.executeLoginCompleted.skip(1).subscribeNextAs {
(isExecuting: Bool) -> () in
//Do something
}
//On error:
self.viewModel.executeSomeActionError.subscribeNextAs {
(error: NSError) -> () in
//Dd something
}
视图模型*
var executeSomeAction: RACCommand?
var executeSomeActionError: RACSignal!
var executeLoginCompleted: RACSignal
executeSomeAction = RACCommand(enabled: combineValidationSignals) {
(any:AnyObject!) -> RACSignal in
println("ANY: \(any)")
return self.executeLoginRequest()
}
executeSomeActionError = executeLogin!.errors
executeLoginCompleted = executeLogin!.executing
当UIView加载时,我应该如何创建RACSignal或RACCommand?当然,遵循MVVM模式。
由于
答案 0 :(得分:0)
您有两种选择。一个比另一个更hacky但更容易在您的应用程序中实现。
选项1:
您可以编写UIViewController的扩展,该扩展使用associatedObjects向UIViewController添加viewDidLoadCommand: RACCommand
属性。然后,您调用UIViewController的viewDidLoad()
方法,以便它在viewDidLoad()
上执行命令:
extension UIViewController {
private struct AssociatedKeys {
static var ViewDidLoadCommand: String = "ViewDidLoadCommand"
}
var viewDidLoadCommand: RACCommand? {
get {
return objc_getAssociatedObject(self, &AssociatedKeys.ViewDidLoadCommand) as? RACCommand
}
set {
if let newValue = newValue {
objc_setAssociatedObject(
self,
&AssociatedKeys.ViewDidLoadCommand,
newValue as RACCommand?,
UInt(OBJC_ASSOCIATION_RETAIN_NONATOMIC)
)
}
}
}
func swizzled_viewDidLoad() {
self.swizzled_viewDidLoad()
self.viewDidLoadCommand?.execute(nil)
}
}
// In the appDelegate
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
method_exchangeImplementations(
class_getInstanceMethod(UIViewController.self, "viewDidLoad"),
class_getInstanceMethod(UIViewController.self, "swizzled_viewDidLoad"))
return true
}
选项2
您可以将UIViewController子类化并实现viewDidLoadCommand
并在viewDidLoad()
class ViewControllerSubClass : UIViewController {
var viewDidLoadCommand: RACCommand?
override func viewDidLoad() {
super.viewDidLoad()
self.viewDidLoadCommand?.execute(nil)
}
}
无论您选择哪种方法,都需要在自定义viewControllers init
方法中设置该命令,并且它将在viewDidLoad
上执行。