├── .gitignore ├── Podfile ├── Podfile.lock ├── README.md ├── ReactiveCocoa-MVVM-AFNetworking-FMDB.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ ├── saitjr.xcuserdatad │ │ └── UserInterfaceState.xcuserstate │ │ └── tangjr.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ ├── saitjr.xcuserdatad │ └── xcschemes │ │ ├── ReactiveCocoa-MVVM-AFNetworking-FMDB.xcscheme │ │ └── xcschememanagement.plist │ └── tangjr.xcuserdatad │ └── xcschemes │ ├── ReactiveCocoa-MVVM-AFNetworking-FMDB.xcscheme │ └── xcschememanagement.plist ├── ReactiveCocoa-MVVM-AFNetworking-FMDB.xcworkspace ├── contents.xcworkspacedata └── xcuserdata │ └── saitjr.xcuserdatad │ ├── UserInterfaceState.xcuserstate │ └── xcdebugger │ └── Breakpoints_v2.xcbkptlist └── ReactiveCocoa-MVVM-AFNetworking-FMDB ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets └── AppIcon.appiconset │ └── Contents.json ├── Base.lproj ├── LaunchScreen.storyboard └── Main.storyboard ├── Category ├── FMDatabaseQueue+Extension.h └── FMDatabaseQueue+Extension.m ├── Configuration ├── CFunctions.h ├── CFunctions.m ├── NotificationNames.h ├── NotificationNames.m ├── SQL.h └── define.h ├── Info.plist ├── Interface └── SQLInterface.h ├── Model ├── Article │ ├── ArticleModel.h │ └── ArticleModel.m └── Base │ ├── BaseModel.h │ └── BaseModel.m ├── Module ├── Base │ ├── ViewController │ │ ├── BaseViewController.h │ │ └── BaseViewController.m │ └── ViewModel │ │ ├── BaseViewModel.h │ │ ├── BaseViewModel.m │ │ ├── RequestViewModel.h │ │ └── RequestViewModel.m └── HomePage │ ├── View │ ├── HomePageCell.h │ └── HomePageCell.m │ ├── ViewController │ ├── HomePageViewController.h │ └── HomePageViewController.m │ └── ViewModel │ ├── HomePageCellViewModel.h │ ├── HomePageCellViewModel.m │ ├── HomePageViewModel.h │ └── HomePageViewModel.m └── main.m /.gitignore: -------------------------------------------------------------------------------- 1 | /Pods 2 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '6.0' 3 | 4 | target 'ReactiveCocoa-MVVM-AFNetworking-FMDB' do 5 | 6 | pod 'ReactiveCocoa', '2.4.7' 7 | pod 'AFNetworking', '2.6.1' 8 | pod 'FMDB', '2.5' 9 | pod 'MJExtension', '2.5.14' 10 | 11 | end 12 | 13 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - AFNetworking (2.6.1): 3 | - AFNetworking/NSURLConnection (= 2.6.1) 4 | - AFNetworking/NSURLSession (= 2.6.1) 5 | - AFNetworking/Reachability (= 2.6.1) 6 | - AFNetworking/Security (= 2.6.1) 7 | - AFNetworking/Serialization (= 2.6.1) 8 | - AFNetworking/UIKit (= 2.6.1) 9 | - AFNetworking/NSURLConnection (2.6.1): 10 | - AFNetworking/Reachability 11 | - AFNetworking/Security 12 | - AFNetworking/Serialization 13 | - AFNetworking/NSURLSession (2.6.1): 14 | - AFNetworking/Reachability 15 | - AFNetworking/Security 16 | - AFNetworking/Serialization 17 | - AFNetworking/Reachability (2.6.1) 18 | - AFNetworking/Security (2.6.1) 19 | - AFNetworking/Serialization (2.6.1) 20 | - AFNetworking/UIKit (2.6.1): 21 | - AFNetworking/NSURLConnection 22 | - AFNetworking/NSURLSession 23 | - FMDB (2.5): 24 | - FMDB/standard (= 2.5) 25 | - FMDB/common (2.5) 26 | - FMDB/standard (2.5): 27 | - FMDB/common 28 | - MJExtension (2.5.14) 29 | - ReactiveCocoa (2.4.7): 30 | - ReactiveCocoa/UI (= 2.4.7) 31 | - ReactiveCocoa/Core (2.4.7): 32 | - ReactiveCocoa/no-arc 33 | - ReactiveCocoa/no-arc (2.4.7) 34 | - ReactiveCocoa/UI (2.4.7): 35 | - ReactiveCocoa/Core 36 | 37 | DEPENDENCIES: 38 | - AFNetworking (= 2.6.1) 39 | - FMDB (= 2.5) 40 | - MJExtension (= 2.5.14) 41 | - ReactiveCocoa (= 2.4.7) 42 | 43 | SPEC CHECKSUMS: 44 | AFNetworking: 8e4e60500beb8bec644cf575beee72990a76d399 45 | FMDB: 96e8f1bcc1329e269330f99770ad4285d9003e52 46 | MJExtension: fb8e6e900fb44c9a7be435ba3d72b7fdf5f0994c 47 | ReactiveCocoa: eb38dee0a0e698f73a9b25e5c1faea2bb4c79240 48 | 49 | PODFILE CHECKSUM: 845d7d4282e7d52d6d87b0528748c68083f8bc62 50 | 51 | COCOAPODS: 1.1.1 52 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ReactiveCocoa-MVVM-AFNetworking-FMDB 2 | 3 | ReactiveCocoa-MVVM-AFNetworking-FMDB小项目框架设计。需要自行 `pod install`。 4 | 5 | 详细介绍见: 6 | 7 | > [小项目框架设计(ReactiveCocoa+MVVM+AFNetworking+FMDB)](http://www.saitjr.com/ios/ios-framework-reactivecocoa-mvvmafnetworking-fmdb.html) 8 | 9 | ## 工程目录 10 | 11 | ![](http://www.brighttj.com/wp-content/uploads/2015/10/ios-framework-reactivecocoa-mvvmafnetworking-fmdb-1.png) 12 | 13 | 1. 【Module】+【Model】 14 | 15 | 在这个目录中,比较核心的是【Module】与【Model】,他们组成了整个MVVM框架。 16 | 17 | 【Module】与【Model】均包含【Base】,其中有`BaseModel`、`BaseViewModel`、`BaseViewController`。在开发中,我还是习惯无论是否需要基类,都去写一个。难免开发之初就考虑到,也难免之后需求会变更。 18 | 19 | 2. 【Interface】接口 20 | 21 | 这是借鉴了Java中的接口思想,目的是为了统一方法名。例如里面的`SQLInterface.h`文件,就是一个对数据进行CRUD操作的`protocol`,并且可以规定里面的方法是否必须实现。 22 | 23 | 3. 【Configuration】配置 24 | 25 | 对项目的一些基本配置,如基本宏定义、常量、通知名,亦或是Cell的identifier。宏定义中一般包含项目基本属性,如:主色调、常用方法等。 26 | 27 | 在提供的Demo中,我将SQL语句放在了`SQL.h`中,是因为SQL只有一个文件在引用,其中的定义方式是: 28 | 29 | ``` objective-c 30 | static NSString * const selectArticleSQL = @"SELECT * FROM article"; 31 | ``` 32 | 33 | 而`NotificationNames.h`会在大部分文件中用到,所以使用`UIKIT_EXTERN`定义为了全局变量: 34 | 35 | ``` objective-c 36 | -----.h 37 | 38 | UIKIT_EXTERN NSString * const LoadAllNotification; 39 | 40 | -----.m 41 | 42 | NSString * const LoadAllNotification = @"LoadAllNotification"; 43 | 44 | ``` 45 | 46 | ​ 47 | 48 | 4. 【Category】类目 49 | 50 | 项目中没有打包的类目,例如给三方或系统类新增的一些方法。 51 | 52 | ## 最后 53 | 54 | 每个项目完后,都会有很多收获,有很多东西需要整理总结。写这篇博客的原因有两个: 55 | 56 | 原因之一:因为我在开发过程中踩了不少坑,可能开发到中途,发现框架设计不好。框架如何设计,并没有一个标准答案,而且设计思想,还需要在不断实践中得出,所以每次总结,是为了给自己看,也是为了帮到其他有同样困扰的朋友。 57 | 58 | 原因之二:也正是因为我不知道框架到底怎么样,所以写出来,让大家看看,都多多提出建议。谢谢。 59 | 60 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0926E6661E8EB52A0097681A /* CFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = 0926E6651E8EB52A0097681A /* CFunctions.m */; }; 11 | 18643FD06147635827F19B20 /* libPods-ReactiveCocoa-MVVM-AFNetworking-FMDB.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FE5617D7D92C1E2857FDB5E2 /* libPods-ReactiveCocoa-MVVM-AFNetworking-FMDB.a */; }; 12 | 9629327F1BD8ACD10087B14B /* BaseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9629327E1BD8ACD10087B14B /* BaseViewController.m */; }; 13 | 962932821BD8ACE80087B14B /* BaseViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 962932811BD8ACE80087B14B /* BaseViewModel.m */; }; 14 | 962932851BD8AD950087B14B /* HomePageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 962932841BD8AD950087B14B /* HomePageViewController.m */; }; 15 | 962932881BD8AF050087B14B /* HomePageViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 962932871BD8AF050087B14B /* HomePageViewModel.m */; }; 16 | 9629328C1BD8B0A90087B14B /* BaseModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 9629328B1BD8B0A90087B14B /* BaseModel.m */; }; 17 | 9629328F1BD8B0BE0087B14B /* ArticleModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 9629328E1BD8B0BE0087B14B /* ArticleModel.m */; }; 18 | 962932921BD8B10B0087B14B /* HomePageCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 962932911BD8B10B0087B14B /* HomePageCell.m */; }; 19 | 9679AF651BD7ED010099BA74 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 9679AF641BD7ED010099BA74 /* main.m */; }; 20 | 9679AF681BD7ED010099BA74 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 9679AF671BD7ED010099BA74 /* AppDelegate.m */; }; 21 | 9679AF6E1BD7ED010099BA74 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9679AF6C1BD7ED010099BA74 /* Main.storyboard */; }; 22 | 9679AF701BD7ED010099BA74 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9679AF6F1BD7ED010099BA74 /* Assets.xcassets */; }; 23 | 9679AF731BD7ED010099BA74 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9679AF711BD7ED010099BA74 /* LaunchScreen.storyboard */; }; 24 | 968EDD861BD8DB0B00CA74F1 /* RequestViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 968EDD851BD8DB0B00CA74F1 /* RequestViewModel.m */; }; 25 | 968EDD891BD8DB5900CA74F1 /* HomePageCellViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 968EDD881BD8DB5900CA74F1 /* HomePageCellViewModel.m */; }; 26 | 968EDD8C1BD9063900CA74F1 /* FMDatabaseQueue+Extension.m in Sources */ = {isa = PBXBuildFile; fileRef = 968EDD8B1BD9063900CA74F1 /* FMDatabaseQueue+Extension.m */; }; 27 | 968EDD9B1BD93B5D00CA74F1 /* NotificationNames.m in Sources */ = {isa = PBXBuildFile; fileRef = 968EDD9A1BD93B5D00CA74F1 /* NotificationNames.m */; }; 28 | /* End PBXBuildFile section */ 29 | 30 | /* Begin PBXFileReference section */ 31 | 0926E6641E8EB52A0097681A /* CFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFunctions.h; sourceTree = ""; }; 32 | 0926E6651E8EB52A0097681A /* CFunctions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CFunctions.m; sourceTree = ""; }; 33 | 34735F8AAA361A0E6B3FBB5D /* Pods-ReactiveCocoa-MVVM-AFNetworking-FMDB.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactiveCocoa-MVVM-AFNetworking-FMDB.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ReactiveCocoa-MVVM-AFNetworking-FMDB/Pods-ReactiveCocoa-MVVM-AFNetworking-FMDB.debug.xcconfig"; sourceTree = ""; }; 34 | 954A0A8FCAC102DB4A39DC22 /* Pods-ReactiveCocoa-MVVM-AFNetworking-FMDB.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactiveCocoa-MVVM-AFNetworking-FMDB.release.xcconfig"; path = "Pods/Target Support Files/Pods-ReactiveCocoa-MVVM-AFNetworking-FMDB/Pods-ReactiveCocoa-MVVM-AFNetworking-FMDB.release.xcconfig"; sourceTree = ""; }; 35 | 9629327D1BD8ACD10087B14B /* BaseViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BaseViewController.h; sourceTree = ""; }; 36 | 9629327E1BD8ACD10087B14B /* BaseViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BaseViewController.m; sourceTree = ""; }; 37 | 962932801BD8ACE80087B14B /* BaseViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BaseViewModel.h; sourceTree = ""; }; 38 | 962932811BD8ACE80087B14B /* BaseViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BaseViewModel.m; sourceTree = ""; }; 39 | 962932831BD8AD950087B14B /* HomePageViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HomePageViewController.h; sourceTree = ""; }; 40 | 962932841BD8AD950087B14B /* HomePageViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HomePageViewController.m; sourceTree = ""; }; 41 | 962932861BD8AF050087B14B /* HomePageViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HomePageViewModel.h; sourceTree = ""; }; 42 | 962932871BD8AF050087B14B /* HomePageViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HomePageViewModel.m; sourceTree = ""; }; 43 | 9629328A1BD8B0A90087B14B /* BaseModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BaseModel.h; sourceTree = ""; }; 44 | 9629328B1BD8B0A90087B14B /* BaseModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BaseModel.m; sourceTree = ""; }; 45 | 9629328D1BD8B0BE0087B14B /* ArticleModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArticleModel.h; sourceTree = ""; }; 46 | 9629328E1BD8B0BE0087B14B /* ArticleModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ArticleModel.m; sourceTree = ""; }; 47 | 962932901BD8B10B0087B14B /* HomePageCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HomePageCell.h; sourceTree = ""; }; 48 | 962932911BD8B10B0087B14B /* HomePageCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HomePageCell.m; sourceTree = ""; }; 49 | 9679AF601BD7ED010099BA74 /* ReactiveCocoa-MVVM-AFNetworking-FMDB.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ReactiveCocoa-MVVM-AFNetworking-FMDB.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | 9679AF641BD7ED010099BA74 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 51 | 9679AF661BD7ED010099BA74 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 52 | 9679AF671BD7ED010099BA74 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 53 | 9679AF6D1BD7ED010099BA74 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 54 | 9679AF6F1BD7ED010099BA74 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 55 | 9679AF721BD7ED010099BA74 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 56 | 9679AF741BD7ED010099BA74 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 57 | 968EDD831BD8D46E00CA74F1 /* SQLInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SQLInterface.h; sourceTree = ""; }; 58 | 968EDD841BD8DB0B00CA74F1 /* RequestViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RequestViewModel.h; sourceTree = ""; }; 59 | 968EDD851BD8DB0B00CA74F1 /* RequestViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RequestViewModel.m; sourceTree = ""; }; 60 | 968EDD871BD8DB5900CA74F1 /* HomePageCellViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HomePageCellViewModel.h; sourceTree = ""; }; 61 | 968EDD881BD8DB5900CA74F1 /* HomePageCellViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HomePageCellViewModel.m; sourceTree = ""; }; 62 | 968EDD8A1BD9063900CA74F1 /* FMDatabaseQueue+Extension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FMDatabaseQueue+Extension.h"; sourceTree = ""; }; 63 | 968EDD8B1BD9063900CA74F1 /* FMDatabaseQueue+Extension.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "FMDatabaseQueue+Extension.m"; sourceTree = ""; }; 64 | 968EDD921BD907B700CA74F1 /* define.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = define.h; sourceTree = ""; }; 65 | 968EDD931BD90D5900CA74F1 /* SQL.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SQL.h; sourceTree = ""; }; 66 | 968EDD991BD93B5D00CA74F1 /* NotificationNames.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NotificationNames.h; sourceTree = ""; }; 67 | 968EDD9A1BD93B5D00CA74F1 /* NotificationNames.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NotificationNames.m; sourceTree = ""; }; 68 | FE5617D7D92C1E2857FDB5E2 /* libPods-ReactiveCocoa-MVVM-AFNetworking-FMDB.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ReactiveCocoa-MVVM-AFNetworking-FMDB.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 69 | /* End PBXFileReference section */ 70 | 71 | /* Begin PBXFrameworksBuildPhase section */ 72 | 9679AF5D1BD7ED010099BA74 /* Frameworks */ = { 73 | isa = PBXFrameworksBuildPhase; 74 | buildActionMask = 2147483647; 75 | files = ( 76 | 18643FD06147635827F19B20 /* libPods-ReactiveCocoa-MVVM-AFNetworking-FMDB.a in Frameworks */, 77 | ); 78 | runOnlyForDeploymentPostprocessing = 0; 79 | }; 80 | /* End PBXFrameworksBuildPhase section */ 81 | 82 | /* Begin PBXGroup section */ 83 | 3D9762975BFDAFEFD8A17395 /* Pods */ = { 84 | isa = PBXGroup; 85 | children = ( 86 | 34735F8AAA361A0E6B3FBB5D /* Pods-ReactiveCocoa-MVVM-AFNetworking-FMDB.debug.xcconfig */, 87 | 954A0A8FCAC102DB4A39DC22 /* Pods-ReactiveCocoa-MVVM-AFNetworking-FMDB.release.xcconfig */, 88 | ); 89 | name = Pods; 90 | sourceTree = ""; 91 | }; 92 | 962932721BD8AC930087B14B /* Model */ = { 93 | isa = PBXGroup; 94 | children = ( 95 | 962932891BD8B0570087B14B /* Article */, 96 | 962932731BD8AC930087B14B /* Base */, 97 | ); 98 | path = Model; 99 | sourceTree = ""; 100 | }; 101 | 962932731BD8AC930087B14B /* Base */ = { 102 | isa = PBXGroup; 103 | children = ( 104 | 9629328A1BD8B0A90087B14B /* BaseModel.h */, 105 | 9629328B1BD8B0A90087B14B /* BaseModel.m */, 106 | ); 107 | path = Base; 108 | sourceTree = ""; 109 | }; 110 | 962932741BD8AC930087B14B /* Module */ = { 111 | isa = PBXGroup; 112 | children = ( 113 | 962932751BD8AC930087B14B /* Base */, 114 | 962932791BD8AC930087B14B /* HomePage */, 115 | ); 116 | path = Module; 117 | sourceTree = ""; 118 | }; 119 | 962932751BD8AC930087B14B /* Base */ = { 120 | isa = PBXGroup; 121 | children = ( 122 | 962932771BD8AC930087B14B /* ViewController */, 123 | 962932781BD8AC930087B14B /* ViewModel */, 124 | ); 125 | path = Base; 126 | sourceTree = ""; 127 | }; 128 | 962932771BD8AC930087B14B /* ViewController */ = { 129 | isa = PBXGroup; 130 | children = ( 131 | 9629327D1BD8ACD10087B14B /* BaseViewController.h */, 132 | 9629327E1BD8ACD10087B14B /* BaseViewController.m */, 133 | ); 134 | path = ViewController; 135 | sourceTree = ""; 136 | }; 137 | 962932781BD8AC930087B14B /* ViewModel */ = { 138 | isa = PBXGroup; 139 | children = ( 140 | 962932801BD8ACE80087B14B /* BaseViewModel.h */, 141 | 962932811BD8ACE80087B14B /* BaseViewModel.m */, 142 | 968EDD841BD8DB0B00CA74F1 /* RequestViewModel.h */, 143 | 968EDD851BD8DB0B00CA74F1 /* RequestViewModel.m */, 144 | ); 145 | path = ViewModel; 146 | sourceTree = ""; 147 | }; 148 | 962932791BD8AC930087B14B /* HomePage */ = { 149 | isa = PBXGroup; 150 | children = ( 151 | 9629327A1BD8AC930087B14B /* View */, 152 | 9629327B1BD8AC930087B14B /* ViewController */, 153 | 9629327C1BD8AC930087B14B /* ViewModel */, 154 | ); 155 | path = HomePage; 156 | sourceTree = ""; 157 | }; 158 | 9629327A1BD8AC930087B14B /* View */ = { 159 | isa = PBXGroup; 160 | children = ( 161 | 962932901BD8B10B0087B14B /* HomePageCell.h */, 162 | 962932911BD8B10B0087B14B /* HomePageCell.m */, 163 | ); 164 | path = View; 165 | sourceTree = ""; 166 | }; 167 | 9629327B1BD8AC930087B14B /* ViewController */ = { 168 | isa = PBXGroup; 169 | children = ( 170 | 962932831BD8AD950087B14B /* HomePageViewController.h */, 171 | 962932841BD8AD950087B14B /* HomePageViewController.m */, 172 | ); 173 | path = ViewController; 174 | sourceTree = ""; 175 | }; 176 | 9629327C1BD8AC930087B14B /* ViewModel */ = { 177 | isa = PBXGroup; 178 | children = ( 179 | 962932861BD8AF050087B14B /* HomePageViewModel.h */, 180 | 962932871BD8AF050087B14B /* HomePageViewModel.m */, 181 | 968EDD871BD8DB5900CA74F1 /* HomePageCellViewModel.h */, 182 | 968EDD881BD8DB5900CA74F1 /* HomePageCellViewModel.m */, 183 | ); 184 | path = ViewModel; 185 | sourceTree = ""; 186 | }; 187 | 962932891BD8B0570087B14B /* Article */ = { 188 | isa = PBXGroup; 189 | children = ( 190 | 9629328D1BD8B0BE0087B14B /* ArticleModel.h */, 191 | 9629328E1BD8B0BE0087B14B /* ArticleModel.m */, 192 | ); 193 | path = Article; 194 | sourceTree = ""; 195 | }; 196 | 962932931BD8B21B0087B14B /* Category */ = { 197 | isa = PBXGroup; 198 | children = ( 199 | 968EDD8A1BD9063900CA74F1 /* FMDatabaseQueue+Extension.h */, 200 | 968EDD8B1BD9063900CA74F1 /* FMDatabaseQueue+Extension.m */, 201 | ); 202 | path = Category; 203 | sourceTree = ""; 204 | }; 205 | 962932941BD8B21B0087B14B /* Configuration */ = { 206 | isa = PBXGroup; 207 | children = ( 208 | 968EDD921BD907B700CA74F1 /* define.h */, 209 | 968EDD931BD90D5900CA74F1 /* SQL.h */, 210 | 968EDD991BD93B5D00CA74F1 /* NotificationNames.h */, 211 | 968EDD9A1BD93B5D00CA74F1 /* NotificationNames.m */, 212 | 0926E6641E8EB52A0097681A /* CFunctions.h */, 213 | 0926E6651E8EB52A0097681A /* CFunctions.m */, 214 | ); 215 | path = Configuration; 216 | sourceTree = ""; 217 | }; 218 | 9679AF571BD7ED010099BA74 = { 219 | isa = PBXGroup; 220 | children = ( 221 | 9679AF621BD7ED010099BA74 /* ReactiveCocoa-MVVM-AFNetworking-FMDB */, 222 | 9679AF611BD7ED010099BA74 /* Products */, 223 | 3D9762975BFDAFEFD8A17395 /* Pods */, 224 | AEB082F248A12C34227626E0 /* Frameworks */, 225 | ); 226 | sourceTree = ""; 227 | }; 228 | 9679AF611BD7ED010099BA74 /* Products */ = { 229 | isa = PBXGroup; 230 | children = ( 231 | 9679AF601BD7ED010099BA74 /* ReactiveCocoa-MVVM-AFNetworking-FMDB.app */, 232 | ); 233 | name = Products; 234 | sourceTree = ""; 235 | }; 236 | 9679AF621BD7ED010099BA74 /* ReactiveCocoa-MVVM-AFNetworking-FMDB */ = { 237 | isa = PBXGroup; 238 | children = ( 239 | 9679AF661BD7ED010099BA74 /* AppDelegate.h */, 240 | 9679AF671BD7ED010099BA74 /* AppDelegate.m */, 241 | 968EDD7F1BD8D40500CA74F1 /* Interface */, 242 | 962932741BD8AC930087B14B /* Module */, 243 | 962932721BD8AC930087B14B /* Model */, 244 | 962932941BD8B21B0087B14B /* Configuration */, 245 | 962932931BD8B21B0087B14B /* Category */, 246 | 9679AF6C1BD7ED010099BA74 /* Main.storyboard */, 247 | 9679AF6F1BD7ED010099BA74 /* Assets.xcassets */, 248 | 9679AF711BD7ED010099BA74 /* LaunchScreen.storyboard */, 249 | 9679AF741BD7ED010099BA74 /* Info.plist */, 250 | 9679AF631BD7ED010099BA74 /* Supporting Files */, 251 | ); 252 | path = "ReactiveCocoa-MVVM-AFNetworking-FMDB"; 253 | sourceTree = ""; 254 | }; 255 | 9679AF631BD7ED010099BA74 /* Supporting Files */ = { 256 | isa = PBXGroup; 257 | children = ( 258 | 9679AF641BD7ED010099BA74 /* main.m */, 259 | ); 260 | name = "Supporting Files"; 261 | sourceTree = ""; 262 | }; 263 | 968EDD7F1BD8D40500CA74F1 /* Interface */ = { 264 | isa = PBXGroup; 265 | children = ( 266 | 968EDD831BD8D46E00CA74F1 /* SQLInterface.h */, 267 | ); 268 | path = Interface; 269 | sourceTree = ""; 270 | }; 271 | AEB082F248A12C34227626E0 /* Frameworks */ = { 272 | isa = PBXGroup; 273 | children = ( 274 | FE5617D7D92C1E2857FDB5E2 /* libPods-ReactiveCocoa-MVVM-AFNetworking-FMDB.a */, 275 | ); 276 | name = Frameworks; 277 | sourceTree = ""; 278 | }; 279 | /* End PBXGroup section */ 280 | 281 | /* Begin PBXNativeTarget section */ 282 | 9679AF5F1BD7ED010099BA74 /* ReactiveCocoa-MVVM-AFNetworking-FMDB */ = { 283 | isa = PBXNativeTarget; 284 | buildConfigurationList = 9679AF771BD7ED010099BA74 /* Build configuration list for PBXNativeTarget "ReactiveCocoa-MVVM-AFNetworking-FMDB" */; 285 | buildPhases = ( 286 | 22D326D250A8E6B08FA90139 /* [CP] Check Pods Manifest.lock */, 287 | 9679AF5C1BD7ED010099BA74 /* Sources */, 288 | 9679AF5D1BD7ED010099BA74 /* Frameworks */, 289 | 9679AF5E1BD7ED010099BA74 /* Resources */, 290 | 354615035DB30FFF7A486D8E /* [CP] Embed Pods Frameworks */, 291 | 63D3076A8FF62DFD8208309C /* [CP] Copy Pods Resources */, 292 | ); 293 | buildRules = ( 294 | ); 295 | dependencies = ( 296 | ); 297 | name = "ReactiveCocoa-MVVM-AFNetworking-FMDB"; 298 | productName = "ReactiveCocoa-MVVM-AFNetworking-FMDB"; 299 | productReference = 9679AF601BD7ED010099BA74 /* ReactiveCocoa-MVVM-AFNetworking-FMDB.app */; 300 | productType = "com.apple.product-type.application"; 301 | }; 302 | /* End PBXNativeTarget section */ 303 | 304 | /* Begin PBXProject section */ 305 | 9679AF581BD7ED010099BA74 /* Project object */ = { 306 | isa = PBXProject; 307 | attributes = { 308 | LastUpgradeCheck = 0700; 309 | ORGANIZATIONNAME = tangjr; 310 | TargetAttributes = { 311 | 9679AF5F1BD7ED010099BA74 = { 312 | CreatedOnToolsVersion = 7.0.1; 313 | }; 314 | }; 315 | }; 316 | buildConfigurationList = 9679AF5B1BD7ED010099BA74 /* Build configuration list for PBXProject "ReactiveCocoa-MVVM-AFNetworking-FMDB" */; 317 | compatibilityVersion = "Xcode 3.2"; 318 | developmentRegion = English; 319 | hasScannedForEncodings = 0; 320 | knownRegions = ( 321 | en, 322 | Base, 323 | ); 324 | mainGroup = 9679AF571BD7ED010099BA74; 325 | productRefGroup = 9679AF611BD7ED010099BA74 /* Products */; 326 | projectDirPath = ""; 327 | projectRoot = ""; 328 | targets = ( 329 | 9679AF5F1BD7ED010099BA74 /* ReactiveCocoa-MVVM-AFNetworking-FMDB */, 330 | ); 331 | }; 332 | /* End PBXProject section */ 333 | 334 | /* Begin PBXResourcesBuildPhase section */ 335 | 9679AF5E1BD7ED010099BA74 /* Resources */ = { 336 | isa = PBXResourcesBuildPhase; 337 | buildActionMask = 2147483647; 338 | files = ( 339 | 9679AF731BD7ED010099BA74 /* LaunchScreen.storyboard in Resources */, 340 | 9679AF701BD7ED010099BA74 /* Assets.xcassets in Resources */, 341 | 9679AF6E1BD7ED010099BA74 /* Main.storyboard in Resources */, 342 | ); 343 | runOnlyForDeploymentPostprocessing = 0; 344 | }; 345 | /* End PBXResourcesBuildPhase section */ 346 | 347 | /* Begin PBXShellScriptBuildPhase section */ 348 | 22D326D250A8E6B08FA90139 /* [CP] Check Pods Manifest.lock */ = { 349 | isa = PBXShellScriptBuildPhase; 350 | buildActionMask = 2147483647; 351 | files = ( 352 | ); 353 | inputPaths = ( 354 | ); 355 | name = "[CP] Check Pods Manifest.lock"; 356 | outputPaths = ( 357 | ); 358 | runOnlyForDeploymentPostprocessing = 0; 359 | shellPath = /bin/sh; 360 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; 361 | showEnvVarsInLog = 0; 362 | }; 363 | 354615035DB30FFF7A486D8E /* [CP] Embed Pods Frameworks */ = { 364 | isa = PBXShellScriptBuildPhase; 365 | buildActionMask = 2147483647; 366 | files = ( 367 | ); 368 | inputPaths = ( 369 | ); 370 | name = "[CP] Embed Pods Frameworks"; 371 | outputPaths = ( 372 | ); 373 | runOnlyForDeploymentPostprocessing = 0; 374 | shellPath = /bin/sh; 375 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ReactiveCocoa-MVVM-AFNetworking-FMDB/Pods-ReactiveCocoa-MVVM-AFNetworking-FMDB-frameworks.sh\"\n"; 376 | showEnvVarsInLog = 0; 377 | }; 378 | 63D3076A8FF62DFD8208309C /* [CP] Copy Pods Resources */ = { 379 | isa = PBXShellScriptBuildPhase; 380 | buildActionMask = 2147483647; 381 | files = ( 382 | ); 383 | inputPaths = ( 384 | ); 385 | name = "[CP] Copy Pods Resources"; 386 | outputPaths = ( 387 | ); 388 | runOnlyForDeploymentPostprocessing = 0; 389 | shellPath = /bin/sh; 390 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ReactiveCocoa-MVVM-AFNetworking-FMDB/Pods-ReactiveCocoa-MVVM-AFNetworking-FMDB-resources.sh\"\n"; 391 | showEnvVarsInLog = 0; 392 | }; 393 | /* End PBXShellScriptBuildPhase section */ 394 | 395 | /* Begin PBXSourcesBuildPhase section */ 396 | 9679AF5C1BD7ED010099BA74 /* Sources */ = { 397 | isa = PBXSourcesBuildPhase; 398 | buildActionMask = 2147483647; 399 | files = ( 400 | 962932881BD8AF050087B14B /* HomePageViewModel.m in Sources */, 401 | 9629328C1BD8B0A90087B14B /* BaseModel.m in Sources */, 402 | 9629327F1BD8ACD10087B14B /* BaseViewController.m in Sources */, 403 | 962932851BD8AD950087B14B /* HomePageViewController.m in Sources */, 404 | 968EDD861BD8DB0B00CA74F1 /* RequestViewModel.m in Sources */, 405 | 962932921BD8B10B0087B14B /* HomePageCell.m in Sources */, 406 | 9629328F1BD8B0BE0087B14B /* ArticleModel.m in Sources */, 407 | 968EDD8C1BD9063900CA74F1 /* FMDatabaseQueue+Extension.m in Sources */, 408 | 9679AF681BD7ED010099BA74 /* AppDelegate.m in Sources */, 409 | 968EDD9B1BD93B5D00CA74F1 /* NotificationNames.m in Sources */, 410 | 9679AF651BD7ED010099BA74 /* main.m in Sources */, 411 | 962932821BD8ACE80087B14B /* BaseViewModel.m in Sources */, 412 | 968EDD891BD8DB5900CA74F1 /* HomePageCellViewModel.m in Sources */, 413 | 0926E6661E8EB52A0097681A /* CFunctions.m in Sources */, 414 | ); 415 | runOnlyForDeploymentPostprocessing = 0; 416 | }; 417 | /* End PBXSourcesBuildPhase section */ 418 | 419 | /* Begin PBXVariantGroup section */ 420 | 9679AF6C1BD7ED010099BA74 /* Main.storyboard */ = { 421 | isa = PBXVariantGroup; 422 | children = ( 423 | 9679AF6D1BD7ED010099BA74 /* Base */, 424 | ); 425 | name = Main.storyboard; 426 | sourceTree = ""; 427 | }; 428 | 9679AF711BD7ED010099BA74 /* LaunchScreen.storyboard */ = { 429 | isa = PBXVariantGroup; 430 | children = ( 431 | 9679AF721BD7ED010099BA74 /* Base */, 432 | ); 433 | name = LaunchScreen.storyboard; 434 | sourceTree = ""; 435 | }; 436 | /* End PBXVariantGroup section */ 437 | 438 | /* Begin XCBuildConfiguration section */ 439 | 9679AF751BD7ED010099BA74 /* Debug */ = { 440 | isa = XCBuildConfiguration; 441 | buildSettings = { 442 | ALWAYS_SEARCH_USER_PATHS = NO; 443 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 444 | CLANG_CXX_LIBRARY = "libc++"; 445 | CLANG_ENABLE_MODULES = YES; 446 | CLANG_ENABLE_OBJC_ARC = YES; 447 | CLANG_WARN_BOOL_CONVERSION = YES; 448 | CLANG_WARN_CONSTANT_CONVERSION = YES; 449 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 450 | CLANG_WARN_EMPTY_BODY = YES; 451 | CLANG_WARN_ENUM_CONVERSION = YES; 452 | CLANG_WARN_INT_CONVERSION = YES; 453 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 454 | CLANG_WARN_UNREACHABLE_CODE = YES; 455 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 456 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 457 | COPY_PHASE_STRIP = NO; 458 | DEBUG_INFORMATION_FORMAT = dwarf; 459 | ENABLE_STRICT_OBJC_MSGSEND = YES; 460 | ENABLE_TESTABILITY = YES; 461 | GCC_C_LANGUAGE_STANDARD = gnu99; 462 | GCC_DYNAMIC_NO_PIC = NO; 463 | GCC_NO_COMMON_BLOCKS = YES; 464 | GCC_OPTIMIZATION_LEVEL = 0; 465 | GCC_PREPROCESSOR_DEFINITIONS = ( 466 | "DEBUG=1", 467 | "$(inherited)", 468 | ); 469 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 470 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 471 | GCC_WARN_UNDECLARED_SELECTOR = YES; 472 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 473 | GCC_WARN_UNUSED_FUNCTION = YES; 474 | GCC_WARN_UNUSED_VARIABLE = YES; 475 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 476 | MTL_ENABLE_DEBUG_INFO = YES; 477 | ONLY_ACTIVE_ARCH = YES; 478 | SDKROOT = iphoneos; 479 | }; 480 | name = Debug; 481 | }; 482 | 9679AF761BD7ED010099BA74 /* Release */ = { 483 | isa = XCBuildConfiguration; 484 | buildSettings = { 485 | ALWAYS_SEARCH_USER_PATHS = NO; 486 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 487 | CLANG_CXX_LIBRARY = "libc++"; 488 | CLANG_ENABLE_MODULES = YES; 489 | CLANG_ENABLE_OBJC_ARC = YES; 490 | CLANG_WARN_BOOL_CONVERSION = YES; 491 | CLANG_WARN_CONSTANT_CONVERSION = YES; 492 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 493 | CLANG_WARN_EMPTY_BODY = YES; 494 | CLANG_WARN_ENUM_CONVERSION = YES; 495 | CLANG_WARN_INT_CONVERSION = YES; 496 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 497 | CLANG_WARN_UNREACHABLE_CODE = YES; 498 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 499 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 500 | COPY_PHASE_STRIP = NO; 501 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 502 | ENABLE_NS_ASSERTIONS = NO; 503 | ENABLE_STRICT_OBJC_MSGSEND = YES; 504 | GCC_C_LANGUAGE_STANDARD = gnu99; 505 | GCC_NO_COMMON_BLOCKS = YES; 506 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 507 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 508 | GCC_WARN_UNDECLARED_SELECTOR = YES; 509 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 510 | GCC_WARN_UNUSED_FUNCTION = YES; 511 | GCC_WARN_UNUSED_VARIABLE = YES; 512 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 513 | MTL_ENABLE_DEBUG_INFO = NO; 514 | SDKROOT = iphoneos; 515 | VALIDATE_PRODUCT = YES; 516 | }; 517 | name = Release; 518 | }; 519 | 9679AF781BD7ED010099BA74 /* Debug */ = { 520 | isa = XCBuildConfiguration; 521 | baseConfigurationReference = 34735F8AAA361A0E6B3FBB5D /* Pods-ReactiveCocoa-MVVM-AFNetworking-FMDB.debug.xcconfig */; 522 | buildSettings = { 523 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 524 | INFOPLIST_FILE = "ReactiveCocoa-MVVM-AFNetworking-FMDB/Info.plist"; 525 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 526 | PRODUCT_BUNDLE_IDENTIFIER = "com.brighttj.tangjr.ReactiveCocoa-MVVM-AFNetworking-FMDB"; 527 | PRODUCT_NAME = "$(TARGET_NAME)"; 528 | }; 529 | name = Debug; 530 | }; 531 | 9679AF791BD7ED010099BA74 /* Release */ = { 532 | isa = XCBuildConfiguration; 533 | baseConfigurationReference = 954A0A8FCAC102DB4A39DC22 /* Pods-ReactiveCocoa-MVVM-AFNetworking-FMDB.release.xcconfig */; 534 | buildSettings = { 535 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 536 | INFOPLIST_FILE = "ReactiveCocoa-MVVM-AFNetworking-FMDB/Info.plist"; 537 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 538 | PRODUCT_BUNDLE_IDENTIFIER = "com.brighttj.tangjr.ReactiveCocoa-MVVM-AFNetworking-FMDB"; 539 | PRODUCT_NAME = "$(TARGET_NAME)"; 540 | }; 541 | name = Release; 542 | }; 543 | /* End XCBuildConfiguration section */ 544 | 545 | /* Begin XCConfigurationList section */ 546 | 9679AF5B1BD7ED010099BA74 /* Build configuration list for PBXProject "ReactiveCocoa-MVVM-AFNetworking-FMDB" */ = { 547 | isa = XCConfigurationList; 548 | buildConfigurations = ( 549 | 9679AF751BD7ED010099BA74 /* Debug */, 550 | 9679AF761BD7ED010099BA74 /* Release */, 551 | ); 552 | defaultConfigurationIsVisible = 0; 553 | defaultConfigurationName = Release; 554 | }; 555 | 9679AF771BD7ED010099BA74 /* Build configuration list for PBXNativeTarget "ReactiveCocoa-MVVM-AFNetworking-FMDB" */ = { 556 | isa = XCConfigurationList; 557 | buildConfigurations = ( 558 | 9679AF781BD7ED010099BA74 /* Debug */, 559 | 9679AF791BD7ED010099BA74 /* Release */, 560 | ); 561 | defaultConfigurationIsVisible = 0; 562 | defaultConfigurationName = Release; 563 | }; 564 | /* End XCConfigurationList section */ 565 | }; 566 | rootObject = 9679AF581BD7ED010099BA74 /* Project object */; 567 | } 568 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB.xcodeproj/project.xcworkspace/xcuserdata/saitjr.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saitjr/ReactiveCocoa-MVVM-AFNetworking-FMDB/5fbbdc1adc2baa29917bfdcda2d04dbeb909d7f2/ReactiveCocoa-MVVM-AFNetworking-FMDB.xcodeproj/project.xcworkspace/xcuserdata/saitjr.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB.xcodeproj/project.xcworkspace/xcuserdata/tangjr.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saitjr/ReactiveCocoa-MVVM-AFNetworking-FMDB/5fbbdc1adc2baa29917bfdcda2d04dbeb909d7f2/ReactiveCocoa-MVVM-AFNetworking-FMDB.xcodeproj/project.xcworkspace/xcuserdata/tangjr.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB.xcodeproj/xcuserdata/saitjr.xcuserdatad/xcschemes/ReactiveCocoa-MVVM-AFNetworking-FMDB.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB.xcodeproj/xcuserdata/saitjr.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | ReactiveCocoa-MVVM-AFNetworking-FMDB.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 9679AF5F1BD7ED010099BA74 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB.xcodeproj/xcuserdata/tangjr.xcuserdatad/xcschemes/ReactiveCocoa-MVVM-AFNetworking-FMDB.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB.xcodeproj/xcuserdata/tangjr.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | ReactiveCocoa-MVVM-AFNetworking-FMDB.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 9679AF5F1BD7ED010099BA74 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB.xcworkspace/xcuserdata/saitjr.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saitjr/ReactiveCocoa-MVVM-AFNetworking-FMDB/5fbbdc1adc2baa29917bfdcda2d04dbeb909d7f2/ReactiveCocoa-MVVM-AFNetworking-FMDB.xcworkspace/xcuserdata/saitjr.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB.xcworkspace/xcuserdata/saitjr.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // ReactiveCocoa-MVVM-AFNetworking-FMDB 4 | // 5 | // Created by TangJR on 10/21/15. 6 | // Copyright © 2015 tangjr. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // ReactiveCocoa-MVVM-AFNetworking-FMDB 4 | // 5 | // Created by TangJR on 10/21/15. 6 | // Copyright © 2015 tangjr. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "FMDatabaseQueue+Extension.h" 11 | #import "SQL.h" 12 | 13 | @interface AppDelegate () 14 | 15 | @end 16 | 17 | @implementation AppDelegate 18 | 19 | 20 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 21 | // Override point for customization after application launch. 22 | 23 | [self configFMDBTables]; 24 | 25 | return YES; 26 | } 27 | 28 | // 创建需要的表 29 | - (void)configFMDBTables { 30 | 31 | [[FMDatabaseQueue shareInstense] inDatabase:^(FMDatabase *db) { 32 | 33 | [db executeUpdate:createArticleSQL]; 34 | }]; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 38 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/Category/FMDatabaseQueue+Extension.h: -------------------------------------------------------------------------------- 1 | // 2 | // FMDatabaseQueue+Extension.h 3 | // ReactiveCocoa-MVVM-AFNetworking-FMDB 4 | // 5 | // Created by TangJR on 10/22/15. 6 | // Copyright © 2015 tangjr. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface FMDatabaseQueue (Extension) 12 | 13 | + (instancetype)shareInstense; 14 | 15 | @end -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/Category/FMDatabaseQueue+Extension.m: -------------------------------------------------------------------------------- 1 | // 2 | // FMDatabaseQueue+Extension.m 3 | // ReactiveCocoa-MVVM-AFNetworking-FMDB 4 | // 5 | // Created by TangJR on 10/22/15. 6 | // Copyright © 2015 tangjr. All rights reserved. 7 | // 8 | 9 | #import "FMDatabaseQueue+Extension.h" 10 | #import "define.h" 11 | 12 | #define DB_PATH [NSString stringWithFormat:@"%@/%@.db", ST_DOCUMENT_DIRECTORY, ST_APP_NAME] 13 | 14 | @implementation FMDatabaseQueue (Extension) 15 | 16 | + (instancetype)shareInstense { 17 | 18 | static FMDatabaseQueue *queue = nil; 19 | 20 | static dispatch_once_t onceToken; 21 | dispatch_once(&onceToken, ^{ 22 | // 根据路径,创建数据库 23 | queue = [FMDatabaseQueue databaseQueueWithPath:DB_PATH]; 24 | }); 25 | 26 | return queue; 27 | } 28 | 29 | @end -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/Configuration/CFunctions.h: -------------------------------------------------------------------------------- 1 | // 2 | // CFunctions.h 3 | // ReactiveCocoa-MVVM-AFNetworking-FMDB 4 | // 5 | // Created by saitjr on 4/1/17. 6 | // Copyright © 2017 tangjr. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSInteger, GlobalErrorType) { 12 | GlobalErrorType_Request, ///< 请求出错 13 | GlobalErrorType_LoadFile, ///< 加载文件出错 14 | GlobalErrorType_Database ///< 数据库错误 15 | }; 16 | FOUNDATION_EXTERN NSString const * GlobalErrorMessageKey; 17 | 18 | FOUNDATION_EXTERN NSError* GlobalError(GlobalErrorType errorType, NSString *msg); 19 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/Configuration/CFunctions.m: -------------------------------------------------------------------------------- 1 | // 2 | // CFunctions.m 3 | // ReactiveCocoa-MVVM-AFNetworking-FMDB 4 | // 5 | // Created by saitjr on 4/1/17. 6 | // Copyright © 2017 tangjr. All rights reserved. 7 | // 8 | 9 | #import "CFunctions.h" 10 | 11 | NSString const * GlobalErrorMessageKey = @"msg"; 12 | 13 | NSError* GlobalError(GlobalErrorType errorType, NSString *msg) { 14 | return [NSError errorWithDomain:@"com.saitjr.demo" code:errorType userInfo:@{GlobalErrorMessageKey : msg}]; 15 | } 16 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/Configuration/NotificationNames.h: -------------------------------------------------------------------------------- 1 | // 2 | // NotificationNames.h 3 | // ReactiveCocoa-MVVM-AFNetworking-FMDB 4 | // 5 | // Created by TangJR on 10/22/15. 6 | // Copyright © 2015 tangjr. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | // 通知名称定义 12 | 13 | UIKIT_EXTERN NSString * const LoadAllNotification; -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/Configuration/NotificationNames.m: -------------------------------------------------------------------------------- 1 | // 2 | // NotificationNames.m 3 | // ReactiveCocoa-MVVM-AFNetworking-FMDB 4 | // 5 | // Created by TangJR on 10/22/15. 6 | // Copyright © 2015 tangjr. All rights reserved. 7 | // 8 | 9 | #import "NotificationNames.h" 10 | 11 | NSString * const LoadAllNotification = @"LoadAllNotification"; 12 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/Configuration/SQL.h: -------------------------------------------------------------------------------- 1 | // 2 | // SQL.h 3 | // ReactiveCocoa-MVVM-AFNetworking-FMDB 4 | // 5 | // Created by TangJR on 10/22/15. 6 | // Copyright © 2015 tangjr. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | // 项目中执行的SQL 12 | 13 | static NSString * const createArticleSQL = @"CREATE TABLE IF NOT EXISTS article (id INT, title VARCHAR, subtitle VARCHAR)"; 14 | 15 | static NSString * const saveArticleSQL = @"INSERT INTO article VALUES (?, ?, ?)"; 16 | static NSString * const deleteArticleSQL = @"DELETE FROM article"; 17 | static NSString * const selectArticleSQL = @"SELECT * FROM article"; 18 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/Configuration/define.h: -------------------------------------------------------------------------------- 1 | // 2 | // define.h 3 | // ReactiveCocoa-MVVM-AFNetworking-FMDB 4 | // 5 | // Created by TangJR on 10/22/15. 6 | // Copyright © 2015 tangjr. All rights reserved. 7 | // 8 | 9 | // 一些常用方法的宏定义,摘自MVVMReactiveCocoa 10 | 11 | #define ST_DOCUMENT_DIRECTORY NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject 12 | 13 | #define ST_APP_NAME ([[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"]) 14 | #define ST_APP_VERSION ([[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]) 15 | #define ST_APP_BUILD ([[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]) -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | NSAppTransportSecurity 22 | 23 | NSAllowsArbitraryLoads 24 | 25 | 26 | CFBundleVersion 27 | 1 28 | LSRequiresIPhoneOS 29 | 30 | UILaunchStoryboardName 31 | LaunchScreen 32 | UIMainStoryboardFile 33 | Main 34 | UIRequiredDeviceCapabilities 35 | 36 | armv7 37 | 38 | UISupportedInterfaceOrientations 39 | 40 | UIInterfaceOrientationPortrait 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/Interface/SQLInterface.h: -------------------------------------------------------------------------------- 1 | // 2 | // SQLInterface.h 3 | // ReactiveCocoa-MVVM-AFNetworking-FMDB 4 | // 5 | // Created by TangJR on 10/22/15. 6 | // Copyright © 2015 tangjr. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | // 数据缓存统一接口,在需要存储数据的类中遵循协议 12 | @protocol SQLInterface 13 | 14 | @optional 15 | - (BOOL)saveData; 16 | - (void)loadData; 17 | - (BOOL)deleteData; 18 | - (BOOL)updateData; 19 | 20 | @end -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/Model/Article/ArticleModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // ArticleModel.h 3 | // ReactiveCocoa-MVVM-AFNetworking-FMDB 4 | // 5 | // Created by TangJR on 10/22/15. 6 | // Copyright © 2015 tangjr. All rights reserved. 7 | // 8 | 9 | #import "BaseModel.h" 10 | 11 | @interface ArticleModel : BaseModel 12 | 13 | @property (copy, nonatomic) NSNumber *articleID; 14 | @property (copy, nonatomic) NSString *title; 15 | @property (copy, nonatomic) NSString *subtitle; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/Model/Article/ArticleModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // ArticleModel.m 3 | // ReactiveCocoa-MVVM-AFNetworking-FMDB 4 | // 5 | // Created by TangJR on 10/22/15. 6 | // Copyright © 2015 tangjr. All rights reserved. 7 | // 8 | 9 | #import "ArticleModel.h" 10 | #import 11 | 12 | @implementation ArticleModel 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/Model/Base/BaseModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // BaseModel.h 3 | // ReactiveCocoa-MVVM-AFNetworking-FMDB 4 | // 5 | // Created by TangJR on 10/22/15. 6 | // Copyright © 2015 tangjr. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BaseModel : NSObject 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/Model/Base/BaseModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // BaseModel.m 3 | // ReactiveCocoa-MVVM-AFNetworking-FMDB 4 | // 5 | // Created by TangJR on 10/22/15. 6 | // Copyright © 2015 tangjr. All rights reserved. 7 | // 8 | 9 | #import "BaseModel.h" 10 | 11 | @implementation BaseModel 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/Module/Base/ViewController/BaseViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // BaseViewController.h 3 | // ReactiveCocoa-MVVM-AFNetworking-FMDB 4 | // 5 | // Created by TangJR on 10/22/15. 6 | // Copyright © 2015 tangjr. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | // 视图控制器基类 12 | @interface BaseViewController : UIViewController 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/Module/Base/ViewController/BaseViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // BaseViewController.m 3 | // ReactiveCocoa-MVVM-AFNetworking-FMDB 4 | // 5 | // Created by TangJR on 10/22/15. 6 | // Copyright © 2015 tangjr. All rights reserved. 7 | // 8 | 9 | #import "BaseViewController.h" 10 | 11 | @interface BaseViewController () 12 | 13 | @end 14 | 15 | @implementation BaseViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view. 20 | 21 | self.view.backgroundColor = [UIColor whiteColor]; 22 | } 23 | 24 | @end -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/Module/Base/ViewModel/BaseViewModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // BaseViewModel.h 3 | // ReactiveCocoa-MVVM-AFNetworking-FMDB 4 | // 5 | // Created by TangJR on 10/22/15. 6 | // Copyright © 2015 tangjr. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | // ViewModel基类 12 | @interface BaseViewModel : NSObject 13 | 14 | @end -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/Module/Base/ViewModel/BaseViewModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // BaseViewModel.m 3 | // ReactiveCocoa-MVVM-AFNetworking-FMDB 4 | // 5 | // Created by TangJR on 10/22/15. 6 | // Copyright © 2015 tangjr. All rights reserved. 7 | // 8 | 9 | #import "BaseViewModel.h" 10 | 11 | @implementation BaseViewModel 12 | 13 | @end -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/Module/Base/ViewModel/RequestViewModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // RequestViewModel.h 3 | // ReactiveCocoa-MVVM-AFNetworking-FMDB 4 | // 5 | // Created by TangJR on 10/22/15. 6 | // Copyright © 2015 tangjr. All rights reserved. 7 | // 8 | 9 | #import "BaseViewModel.h" 10 | #import 11 | 12 | typedef NS_ENUM(NSInteger, RequestErrorCode) { 13 | RequestErrorCode_None, 14 | RequestErrorCode_ParameterError = 1, ///< 参数错误 15 | RequestErrorCode_LoginRequired = 2, ///< 用户未登录 16 | RequestErrorCode_NoData = 3 ///< 暂无数据 17 | }; 18 | 19 | // 继承自BaseViewModel 20 | // 需要网络请求的VM继承该类 21 | // 该类有一个公共属性sessionManager,一个该属性的懒加载方法和一个dealloc中取消网络请求的方法 22 | @interface RequestViewModel : BaseViewModel 23 | 24 | @property (strong, nonatomic) AFHTTPSessionManager *sessionManager; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/Module/Base/ViewModel/RequestViewModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // RequestViewModel.m 3 | // ReactiveCocoa-MVVM-AFNetworking-FMDB 4 | // 5 | // Created by TangJR on 10/22/15. 6 | // Copyright © 2015 tangjr. All rights reserved. 7 | // 8 | 9 | #import "RequestViewModel.h" 10 | 11 | @implementation RequestViewModel 12 | 13 | // 懒加载 14 | - (AFHTTPSessionManager *)sessionManager { 15 | 16 | if (!_sessionManager) { 17 | _sessionManager = [AFHTTPSessionManager manager]; 18 | _sessionManager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html", nil]; 19 | _sessionManager.requestSerializer.timeoutInterval = 30; 20 | } 21 | return _sessionManager; 22 | } 23 | 24 | // 在对象销毁时,别忘了取消已经在队列中的请求 25 | - (void)dealloc { 26 | 27 | [self.sessionManager invalidateSessionCancelingTasks:YES]; 28 | } 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/Module/HomePage/View/HomePageCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // HomePageCell.h 3 | // ReactiveCocoa-MVVM-AFNetworking-FMDB 4 | // 5 | // Created by TangJR on 10/22/15. 6 | // Copyright © 2015 tangjr. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "HomePageCellViewModel.h" 11 | 12 | @interface HomePageCell : UITableViewCell 13 | 14 | // cell的VM 15 | @property (strong, nonatomic) HomePageCellViewModel *viewModel; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/Module/HomePage/View/HomePageCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // HomePageCell.m 3 | // ReactiveCocoa-MVVM-AFNetworking-FMDB 4 | // 5 | // Created by TangJR on 10/22/15. 6 | // Copyright © 2015 tangjr. All rights reserved. 7 | // 8 | 9 | #import "HomePageCell.h" 10 | #import 11 | 12 | @implementation HomePageCell 13 | 14 | - (void)awakeFromNib { 15 | [super awakeFromNib]; 16 | 17 | [self setupSignal]; 18 | } 19 | 20 | // 设置信号量,当cell的vm被重新赋值时,更新cell显示的数据 21 | - (void)setupSignal { 22 | 23 | @weakify(self); 24 | [RACObserve(self, viewModel) subscribeNext:^(HomePageCellViewModel *viewModel) { 25 | 26 | // 使用strong修饰self,防止在self在使用中被释放 27 | @strongify(self); 28 | 29 | // vm已经将要显示的文本处理好了,在cell中直接赋值就行 30 | self.textLabel.text = viewModel.titleText; 31 | self.detailTextLabel.text = viewModel.subtitleText; 32 | }]; 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/Module/HomePage/ViewController/HomePageViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // HomePageViewController.h 3 | // ReactiveCocoa-MVVM-AFNetworking-FMDB 4 | // 5 | // Created by TangJR on 10/22/15. 6 | // Copyright © 2015 tangjr. All rights reserved. 7 | // 8 | 9 | #import "BaseViewController.h" 10 | 11 | @interface HomePageViewController : BaseViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/Module/HomePage/ViewController/HomePageViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // HomePageViewController.m 3 | // ReactiveCocoa-MVVM-AFNetworking-FMDB 4 | // 5 | // Created by TangJR on 10/22/15. 6 | // Copyright © 2015 tangjr. All rights reserved. 7 | // 8 | 9 | #import "HomePageViewController.h" 10 | #import "HomePageViewModel.h" 11 | #import "HomePageCell.h" 12 | #import "CFunctions.h" 13 | 14 | @interface HomePageViewController () 15 | 16 | @property (weak, nonatomic) IBOutlet UITableView *tableView; 17 | 18 | // vm 19 | @property (strong, nonatomic) HomePageViewModel *viewModel; 20 | 21 | @end 22 | 23 | @implementation HomePageViewController 24 | 25 | - (void)viewDidLoad { 26 | [super viewDidLoad]; 27 | // Do any additional setup after loading the view. 28 | 29 | [self sendRequest]; 30 | } 31 | 32 | // 发起请求 33 | - (void)sendRequest { 34 | 35 | @weakify(self); 36 | [self.viewModel.requestSignal subscribeNext:^(NSArray *articles) { 37 | 38 | @strongify(self); 39 | // 请求完成后,刷新表格 40 | [self.tableView reloadData]; 41 | } error:^(NSError *error) { 42 | // 如果请求失败,则根据error做出相应提示 43 | NSString *msg = [[error userInfo] objectForKey:GlobalErrorMessageKey]; 44 | 45 | UIAlertAction *action = [UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleCancel handler:NULL]; 46 | UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"温馨提示" message:msg preferredStyle:UIAlertControllerStyleAlert]; 47 | [alert addAction:action]; 48 | [self presentViewController:alert animated:YES completion:NULL]; 49 | }]; 50 | } 51 | 52 | #pragma mark - UITableViewDataSource 53 | 54 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 55 | 56 | HomePageCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"]; 57 | [self configCell:cell indexPath:indexPath]; 58 | return cell; 59 | } 60 | 61 | - (void)configCell:(HomePageCell *)cell indexPath:(NSIndexPath *)indexPath { 62 | 63 | // 将数据赋值给cell的vm 64 | // cell接收到vm修改以后,就会触发初始时设置的信号量 65 | cell.viewModel = self.viewModel.dataSource[indexPath.row]; 66 | } 67 | 68 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 69 | 70 | return self.viewModel.dataSource.count; 71 | } 72 | 73 | #pragma mark - Lazy Load 74 | 75 | - (HomePageViewModel *)viewModel { 76 | 77 | if (!_viewModel) { 78 | _viewModel = [HomePageViewModel new]; 79 | } 80 | return _viewModel; 81 | } 82 | 83 | @end 84 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/Module/HomePage/ViewModel/HomePageCellViewModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // HomePageCellViewModel.h 3 | // ReactiveCocoa-MVVM-AFNetworking-FMDB 4 | // 5 | // Created by TangJR on 10/22/15. 6 | // Copyright © 2015 tangjr. All rights reserved. 7 | // 8 | 9 | #import "BaseViewModel.h" 10 | #import "ArticleModel.h" 11 | 12 | // cell的vm 13 | // 无需网络请求,所以继承BaseViewModel即可 14 | @interface HomePageCellViewModel : BaseViewModel 15 | 16 | @property (strong, nonatomic) ArticleModel *articleModel; 17 | 18 | @property (copy, nonatomic, readonly) NSString *titleText; 19 | @property (copy, nonatomic, readonly) NSString *subtitleText; 20 | @property (copy, nonatomic, readonly) NSString *idText; 21 | 22 | - (instancetype)initWithArticleModel:(ArticleModel *)articleModel; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/Module/HomePage/ViewModel/HomePageCellViewModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // HomePageCellViewModel.m 3 | // ReactiveCocoa-MVVM-AFNetworking-FMDB 4 | // 5 | // Created by TangJR on 10/22/15. 6 | // Copyright © 2015 tangjr. All rights reserved. 7 | // 8 | 9 | #import "HomePageCellViewModel.h" 10 | 11 | @interface HomePageCellViewModel () 12 | 13 | @end 14 | 15 | @implementation HomePageCellViewModel 16 | 17 | - (instancetype)initWithArticleModel:(ArticleModel *)articleModel { 18 | 19 | self = [super init]; 20 | 21 | if (self) { 22 | self.articleModel = articleModel; 23 | [self setupData]; 24 | } 25 | 26 | return self; 27 | } 28 | 29 | // 处理Model中的数据 30 | // 这里的处理不是很复杂,仅仅作为例子 31 | - (void)setupData { 32 | _titleText = self.articleModel.title; 33 | _subtitleText = self.articleModel.subtitle; 34 | _idText = self.articleModel.articleID.stringValue; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/Module/HomePage/ViewModel/HomePageViewModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // HomePageViewModel.h 3 | // ReactiveCocoa-MVVM-AFNetworking-FMDB 4 | // 5 | // Created by TangJR on 10/22/15. 6 | // Copyright © 2015 tangjr. All rights reserved. 7 | // 8 | 9 | #import "RequestViewModel.h" 10 | #import "ArticleModel.h" 11 | #import "SQLInterface.h" 12 | #import 13 | 14 | // vc的vm 15 | // 因为需要进行数据缓存,所以遵循SQLInterface 16 | // 因为需要进行网络请求,所以继承自RequestViewModel 17 | 18 | @interface HomePageViewModel : RequestViewModel 19 | 20 | @property (strong, nonatomic) RACSignal *requestSignal; ///< 网络请求信号量 21 | 22 | @property (assign, nonatomic) NSInteger currentPage; ///< 当前页码 23 | @property (strong, nonatomic) NSArray *dataSource; ///< tableView的数据源 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/Module/HomePage/ViewModel/HomePageViewModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // HomePageViewModel.m 3 | // ReactiveCocoa-MVVM-AFNetworking-FMDB 4 | // 5 | // Created by TangJR on 10/22/15. 6 | // Copyright © 2015 tangjr. All rights reserved. 7 | // 8 | 9 | #import "HomePageViewModel.h" 10 | #import "HomePageCellViewModel.h" 11 | #import "FMDatabaseQueue+Extension.h" 12 | #import "SQL.h" 13 | #import "CFunctions.h" 14 | #import 15 | 16 | @interface HomePageViewModel () 17 | 18 | @property (strong, nonatomic) NSMutableArray *articleViewModels; ///< 这个属性主要存储的是文章的vm,上拉加载的时候追加,下拉刷新的时候清空。防止直接修改dataSource 19 | @property (assign, nonatomic) BOOL isRefresh; ///< 是否是刷新(用于处理数据缓存与dataSource) 20 | 21 | @end 22 | 23 | @implementation HomePageViewModel 24 | 25 | #pragma mark - SQLInterface 26 | 27 | - (BOOL)saveData { 28 | 29 | // 需要在block中进行修改变量值,所以用__block修饰 30 | __block BOOL isSuccess = NO; 31 | 32 | // 批量操作,选择事务 33 | [[FMDatabaseQueue shareInstense] inTransaction:^(FMDatabase *db, BOOL *rollback) { 34 | 35 | for (HomePageCellViewModel *cellViewModel in self.dataSource) { 36 | 37 | ArticleModel *articleModel = cellViewModel.articleModel; 38 | 39 | // 存储 40 | isSuccess = [db executeUpdate:saveArticleSQL, articleModel.articleID, articleModel.title, articleModel.subtitle]; 41 | // 如果有失败,则停止,跳出循环 42 | if (!isSuccess) { 43 | break; 44 | } 45 | } 46 | // 如果遇到失败,则回滚,存储失败 47 | if (!isSuccess) { 48 | *rollback = YES; 49 | return; 50 | } 51 | }]; 52 | 53 | return isSuccess; 54 | } 55 | 56 | - (BOOL)deleteData { 57 | 58 | __block BOOL isSuccess = NO; 59 | 60 | [[FMDatabaseQueue shareInstense] inDatabase:^(FMDatabase *db) { 61 | 62 | isSuccess = [db executeUpdate:deleteArticleSQL]; 63 | }]; 64 | 65 | return isSuccess; 66 | } 67 | 68 | - (void)loadData { 69 | 70 | [[FMDatabaseQueue shareInstense] inDatabase:^(FMDatabase *db) { 71 | 72 | // 读取数据 73 | FMResultSet *set = [db executeQuery:selectArticleSQL]; 74 | 75 | // 循环读取,直到读完 76 | while ([set next]) { 77 | ArticleModel *article = [ArticleModel new]; 78 | article.title = [set objectForColumnName:@"title"]; 79 | article.articleID = [set objectForColumnName:@"id"]; 80 | article.subtitle = [set objectForColumnName:@"subtitle"]; 81 | HomePageCellViewModel *cellViewModel = [[HomePageCellViewModel alloc] initWithArticleModel:article]; 82 | [self.articleViewModels addObject:cellViewModel]; 83 | } 84 | // 关闭结果集 85 | [set close]; 86 | }]; 87 | // 读取完后重新赋值给dataSource 88 | self.dataSource = [self.articleViewModels copy]; 89 | } 90 | 91 | #pragma mark - Getter / Setter 92 | 93 | // 采用懒加载的方式来配置网络请求 94 | - (RACSignal *)requestSignal { 95 | 96 | if (!_requestSignal) { 97 | 98 | @weakify(self); 99 | _requestSignal = [RACSignal createSignal:^RACDisposable *(id subscriber) { 100 | 101 | @strongify(self); 102 | 103 | // 配置网络请求参数 104 | NSDictionary *parameters = @{@"page": @(self.currentPage)}; 105 | 106 | // 发起请求 107 | NSURLSessionDataTask *task = [self.sessionManager GET:@"http://www.saitjr.com/api_for_test/static_article_list.php" parameters:parameters success:^(NSURLSessionDataTask * _Nonnull task, id _Nonnull responseObject) { 108 | // 可封装为请求正确,但是校验未通过处理 109 | if ([responseObject[@"code"] integerValue] == RequestErrorCode_NoData) { 110 | [subscriber sendNext:nil]; 111 | [subscriber sendError:GlobalError(GlobalErrorType_Request, @"没数据啦")]; 112 | return; 113 | } 114 | 115 | // 将请求下来的字典->模型 116 | NSArray *articleArray = responseObject[@"data"]; 117 | for (NSDictionary *articleDictionary in articleArray) { 118 | ArticleModel *articleModel = [ArticleModel objectWithKeyValues:articleDictionary]; 119 | // 根据模型,初始化cell的vm 120 | HomePageCellViewModel *cellViewModel = [[HomePageCellViewModel alloc] initWithArticleModel:articleModel]; 121 | // 将cell的vm存入数组 122 | [self.articleViewModels addObject:cellViewModel]; 123 | } 124 | // 完成数据处理后,赋值给dataSource 125 | self.dataSource = [self.articleViewModels copy]; 126 | 127 | // 如果是刷新操作,则删除数据库中的旧数据 128 | // 这里也可以采用存入部分新数据的方式,全部删除可能在效率方面不是很好 129 | if (self.isRefresh) { 130 | [self deleteData]; 131 | } 132 | // 存入新数据 133 | [self saveData]; 134 | 135 | [subscriber sendNext:self.dataSource]; 136 | [subscriber sendCompleted]; 137 | } failure:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nonnull error) { 138 | 139 | // 如果网络请求出错,则加载数据库中的旧数据 140 | [self loadData]; 141 | [subscriber sendNext:self.dataSource]; 142 | [subscriber sendError:GlobalError(GlobalErrorType_Request, @"网络错误")]; 143 | }]; 144 | 145 | // 在信号量作废时,取消网络请求 146 | return [RACDisposable disposableWithBlock:^{ 147 | 148 | [task cancel]; 149 | }]; 150 | }]; 151 | } 152 | return _requestSignal; 153 | } 154 | 155 | - (BOOL)isRefresh { 156 | 157 | _isRefresh = self.currentPage == 0; 158 | 159 | return _isRefresh; 160 | } 161 | 162 | - (NSMutableArray *)articleViewModels { 163 | 164 | if (!_articleViewModels) { 165 | _articleViewModels = [NSMutableArray new]; 166 | } 167 | return _articleViewModels; 168 | } 169 | 170 | @end 171 | -------------------------------------------------------------------------------- /ReactiveCocoa-MVVM-AFNetworking-FMDB/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // ReactiveCocoa-MVVM-AFNetworking-FMDB 4 | // 5 | // Created by TangJR on 10/21/15. 6 | // Copyright © 2015 tangjr. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | --------------------------------------------------------------------------------