The previous project used the Reactivecocoa+MVVM+afnetworking+FMDB framework design, from the initial attempt, to the subsequent continuous thinking and learning, Now for such a whole design still have a certain understanding and experience. Share with you here.
This article will no longer describe the details of the use of Reactivecocoa,MVVM, andFMDB . About Reactivecocoa, I have a practical case blog:
Http://www.brighttj.com/ios/ios-reactivecocoa-utility-demo.html
The article describes more of my understanding of the framework design, rather than the specific code of the logic of the explanation. For the code logic, I will give a detailed comment in the demo, this article demo:
Https://github.com/saitjr/ReactiveCocoa-MVVM-AFNetworking-FMDB.git
Environmental information:
Mac OS X 10.11
Xcode 7.0.1
IOS 9.0.1
Reactivecocoa 2.4.7
Afnetworking 2.6.1
FMDB 2.5
Mjextension 2.5.14
Body
Project Catalogue
Let's talk about the engineering catalogue.
Project Catalogue
1. "Module" + "Model"
In this directory, the core of the comparison is "Module" and "Model", they make up the entire MVVM framework.
Both "Module" and "Model" contain "Base", including Basemodel,baseviewmodel,baseviewcontroller. In development, I am still accustomed to write one regardless of whether I need a base class. Inevitably at the beginning of the development of the consideration, but also inevitably after the demand will change.
2. "Interface" interface
This is borrowed from the Java interface idea, the purpose is to unify the method name. For example, the SQLInterface.h file inside is a protocolfor CRUD operations on the data, and can specify whether the method must be implemented.
3. "Configuration" configurations
Some basic configuration of the project, such as basic macro definitions, constants, notification names, or cell identifier. Macro definitions generally include the basic properties of the project, such as: main tones, common methods, and so on.
In the demo provided, I put the SQL statement in SQL.h because there is only one file in SQL that is referenced, which is defined in the following way:
static NSString * const selectArticleSQL = @"SELECT * FROM article";
NotificationNames.h is used in most files, so the uikit_extern is defined for global variables:
-----.hUIKIT_EXTERN NSString * const LoadAllNotification;-----.mNSString * const LoadAllNotification = @"LoadAllNotification";
5 category "category"
There are no packaged classes in the project, such as new methods for three-party or system classes.
Rac+mvvm
RAC+MVVM is implemented in both the "Module" and "Model" directories. In this, MVVM is a framework idea, and RAC is just a helper.
One, MVVM
The reason for using MVVM, rather than MVC, is also due to the big feature of MVVM, which is to reduce the burden on the C layer, after all, the previous C layer is a treasure chest, and what code is written in it.
For MVVM my understanding and splitting is this:
1. Model and view
This layer has the same meaning as the model and view in MVC.
2. ViewModel
The main role of this layer is to put the data previously written in Viewcontroller in the ViewModel , such as: network requests, data caching, can not directly display the data processing (such as NSNumber , such as, is processed into nsstringin the VM, and then the V layer is used directly instead of in the V layer.
Second, the design of VC in demo
Graphics combined with the source code should be able to see a ballpark.
VC Design
Third, custom cell design (can be extended to the design of Custom view)
Because the introduction is VC, so here to say a bit of Homepagecell this custom cell design.
Because there may be more complex cells in the actual project, the demo is written in a more complete way (if you look at this demo alone, this custom cell is too simple to have a single VM, a bit over-engineered).
The idea in the cell is that the cell has a CELLVM to manage the data to be displayed in the cell,CELLVM from the VC ,dataSource array. This is done in the following way: After the network request is complete, the dictionary---model, then initializes the CELLVMthrough the model, and then puts the CELLVM into the dataSource array.
The Cell Implementation section code is as follows:
@implementation HomePageCell- (void)awakeFromNib { [super awakeFromNib]; [self setupSignal];}- (void)setupSignal { @weakify(self); [RACObserve(self, viewModel) subscribeNext:^(HomePageCellViewModel *viewModel) { @strongify(self); self.textLabel.text = viewModel.titleText; self.detailTextLabel.text = viewModel.authorText; }];}@end
Afnetworking
A few days ago,afnetworking upgraded to 3.0. The previous nsurlconnection -based API, all changed to nsurlsession, about the update details, you can see Afnetworking 3.0 Migration Guide this article.
In the case of page destruction, re-request, and so on, you need to cancel the request that is still in the queue, so as not to occupy resources.
With this in mind, the combination of my network request was sent on the VM, weighed again and again, on the basis of Baseviewmodel , and then a package-Requestviewmodel. This VM has the properties of the Afhttpsessionmanager class, a lazy load of the property, and a cancellation request method in Dealloc .
In the previous use of MVC, I will afnetworking the package again, so more like a mvcs design, the purpose is to prevent the VC overweight, now put this part of the code in the VM, looks OK, so there is no Afnetworking the package again. For the previous design method, you can read this article:
Network Request Framework Encapsulation
FMDB
Fmdb provides a thread-safe mode in which to maintain this serial queue.
1. Initialization
The initialization method references the open source project Mvvmreactivecocoa, the author uses the class purpose form to give a singleton:
@implementation FMDatabaseQueue (Extension)+ (instancetype)shareInstense { static FMDatabaseQueue *queue = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ queue = [FMDatabaseQueue databaseQueueWithPath:DB_PATH]; }); return queue;}@end
2. Unified interface
As for the definition of crud methods, the design of Java interface is used for reference:
3. SQL statements
According to the actual situation, SQL statement parameters can be used? form, can also be used: keyword form.
INSERT INTO myTable VALUES (?, ?, ?)INSERT INTO myTable VALUES (:id, :name, :value)
Regarding the creation and update of the database, I do not recommend that the Bundle contain xxx.sql files, because they will be packaged together after compilation, the user can see the download decompression, and not very safe. At present I am directly in the program to write SQL, do not know everyone has no better way.
4. CRUD
When the network request succeeds, the data is deposited. Storage is a batch operation, and it is recommended to implement it with transaction intransaction . Simple operation using the indatabase can be.
Fmdatabasequeue is a serial queue, and both intransaction and indatabase are synchronous threads, and it is important to note that you do not perform another database access operation in the block To prevent thread deadlock.
At last
After each project, there will be a lot of harvest, there are a lot of things to summarize. There are two reasons to write this blog:
One of the reasons: because I stepped on a lot of holes in the development process, may develop to halfway, found that the frame design is not good. Framework how to design, and do not have a standard answer, and design ideas, but also need to be in practice, so each summary, is to give themselves to see, but also to help others have the same troubled friends.
The second reason: it is because I do not know what the framework is, so write it, let us look at it, and make a lot of suggestions. Thank you.
Reference
1. Reichen Open Source Project Mvvmreactivecocoa, this project to my inspiration is very big, here thank the author, also for open source point likes
2. iOS large-scale project development ramble
3. iOS application architecture talk about network design
"IOS" Small Project Framework Design (REACTIVECOCOA+MVVM+AFNETWORKING+FMDB)