MvvmForIOSSwift 0.7

MvvmForIOSSwift 0.7

Francois Dabonot 维护。



  • Francois Dabonot

MvvmForIOS-Swift

MvvmForIOS 是一个在 iOS 上使用 Mvvm 模式的框架。

它完全使用 Swift 4 编写,并包含一些工具,以尊重 mvvm 模式。

框架内容

  • 结构 View/ViewModel/Model
  • 导航服务,用于管理 viewModel 之间的导航
  • 服务定位器,用于 IoC 功能

兼容性

  • Swift 4
  • iOS 8

绑定问题?

MvvmForIOS-Swift 没有绑定工具。

目前,我建议使用 Bond (https://github.com/DeclarativeHub/Bond)

此框架专门用于在视图和 viewModel 之间绑定内容

您还可以使用 KVO,但它与 Swift 不完全兼容。

如何安装 MvvmForIOS-Swift

  • Carthage

github "Friend-LGA/LGSideMenuController"

github "frankois944/MvvmForIOS-Swift"

  • CocoaPods

pod 'MvvmForIOSSwift'

如何使用它

以下示例说明了如何在Swift项目中实现框架而不进行绑定。

服务定位器

有一个服务定位器可以用于IoC。

//interface
protocol IDataServices : class {
    var name:String! { get }
    func openApplicationSetting() -> Bool
}

class DataServices: IDataServices {
    // ...implement protocol
}

//save
ServiceLocator.register(service: DataServices() as IDataServices)
//get
let service:IDataServices! = ServiceLocator.resolve()
let result = service.openApplicationSetting()

导航

重要

导航是通过 INavigationService 来管理的。

它还基于 LGSideMenuController 框架 (https://github.com/Friend-LGA/LGSideMenuController)。

所有 视图 间的导航都在 ViewModel 中进行,这要求 视图 + (Storyboard) 和相应的 ViewModel 之间有一些特定的命名。

对于 ViewModeltestViewModel视图Must命名为 testView,Storyboard命名为 test

如果不遵守这一规则,导航将无法工作。

那么如何导航呢?

在ViewModel中只需调用

//Show
self.navigation.showViewModel(viewModelToShow: AnotherViewModel.self)
or 
self.navigation.showViewModel(viewModelToShow: AnotherViewModel.self, onCompletion:nil, withParameters:[SOMEDATA])

//Inside AnotherViewModel 
override func startViewModel(parameters: Any? [SOMEDATA]) {
        
}
//Close
self.navigation.closeViewModel(viewModelToClose: self, onCompletion: { () -> (Void) in
    NSLog("AnotherViewModel closed")
})

INavigationService 接口

INavigationService 有许多导航方法,带有完成情况、参数等。

public protocol INavigationService {
    var navigation:LGSideMenuController { get }

    func setCenterViewModel<T:IBaseViewModel>(viewModelToShow:T.Type!) -> Void
    func setRightSideViewModel<T:IBaseViewModel>(viewModelToShow:T.Type!) -> Void
    func setLeftSideViewModel<T:IBaseViewModel>(viewModelToShow:T.Type!) -> Void
    
    func showViewModel<T:IBaseViewModel>(viewModelToShow:T.Type!) -> Void
    func showViewModel<T:IBaseViewModel>(viewModelToShow:T.Type!, onCompletion:(() -> (Void))?) -> Void
    func showViewModel<T:IBaseViewModel>(viewModelToShow:T.Type!, onCompletion:(() -> (Void))?, withParameters:AnyObject?) -> Void
    
    func showModalViewModel<T:IBaseViewModel>(viewModelToShow:T.Type!) -> Void
    func showModalViewModel<T:IBaseViewModel>(viewModelToShow:T.Type!, onCompletion:(() -> (Void))?) -> Void
    func showModalViewModel<T:IBaseViewModel>(viewModelToShow:T.Type!, onCompletion:(() -> (Void))?, customizeModal:((UIViewController) -> (Void))?) -> Void
    func showModalViewModel<T:IBaseViewModel>(viewModelToShow:T.Type!, onCompletion:(() -> (Void))?, customizeModal:((UIViewController) -> (Void))?, withParameters:AnyObject?) -> Void
    
    func closeViewModel<T:IBaseViewModel>(viewModelToClose:T!, onCompletion:(() -> (Void))?) -> Void
    func closeViewModel<T:IBaseViewModel>(viewModelToClose:T!) -> Void
    
    func showLeftPanel(animated:Bool) -> Void
    func showRightPanel(animated:Bool) -> Void
    func hideLeftPanel(animated:Bool) -> Void
    func hideRightPanel(animated:Bool) -> Void
    
    func resolveViewModel<T:IBaseViewModel>(viewModelToGet:T.Type!) -> T!
}

侧边栏

  • 因为这个框架基于 LGSideMenuController,所以使用面板非常简单
//in the appDelegate, set root view for Panel
navigation.setCenterViewModel(viewModelToShow: FirstViewModel.self)
navigation.setLeftSideViewModel(viewModelToShow: SecondViewModel.self)
navigation.setRightSideViewModel(viewModelToShow: SecondViewModel.self)

//in a viewModel
//show
navigation.showLeftPanel(animated: true)
navigation.showRightPanel(animated: true)
//hide
navigation.hideLeftPanel(animated: true)
navigation.hideRightPanel(animated: true)
  • 您还可以在侧边面板中推送一个viewModel
the view declaration must have 
class SecondView: BaseView<SecondViewModel>, ILeftPanelAttribute /*mandatory*/ {
//implementation
}
navigation.showViewModel(viewModelToShow: SecondViewModel.self)
  • 您可以通过以下方式访问到 LGSideMenuController
let lgSideCtr = navigation.navigation;

因此,您可以自定义此组件。