I’ll tell you what I know (MVVM) (iOS)

Before writing this article, this is the first time I use MVVM to write a small Demo. Work more than a year to write MVVM, way: to know RAC from the first RAC has spent a lot of time, and secondly, has been thinking about how to write MVVM. Now it’s time for me to write a Demo. I think the most direct way to learn programming is to write something, so you will find a lot of problems, will grow faster. Of course, now feel that there will be a lot of problems, I hope everyone pointing out the purpose is to send more people to see, can give more suggestions.

MVVM this thing, seemingly mysterious, in fact, there is no difference between the essence and MVC (which means that the loading force).

First of all, to explain, before using MVVM, it is best to know about RAC, check a lot of information, found that these two basic is not separated. Second, if you use RAC, even if you use the MVC, it will reduce the pressure on the C. So RAC is a good thing, but I am not very proficient (this sentence is very comfortable).

I know a good video: Although the time is early, but it is the essence.
https://pan.baidu.com/s/1hr8omLA
I am through this video to understand the RAC, but I began to know RAC when it is six months later. So we do not worry, slowly groping.

Words do not say, into the subject, here we have to imitate the details page to do JD.

First look at the interface

I'll tell you what I know (MVVM) (iOS)
Paste_Image.png

I'll tell you what I know (MVVM) (iOS)
Paste_Image.png

When I see these two interface, I have a little side, as if there is no law.

Although I have seen several interfaces, suddenly aware of one thing, this may be related to the data, let us look at the data, where we can use Charles blue and white porcelain to grab.

To start our real first step, grab data

Recommended Charles article: http://blog.devtang.com/2015/11/14/charles-introduction/

I'll tell you what I know (MVVM) (iOS)
Paste_Image.png

Here in brief, you may find a connection with a small lock a lot of data, this is to remind you, you need a SSL certificate, after the installation is complete, click on the right button, and then click on the Enbale SSL Proxying, and then try to grab it, like the one above.

I'll tell you what I know (MVVM) (iOS)
Paste_Image.png

This is what we need.

Sorry to write articles like music, the lower left corner is the lyrics, I forgive you.

These two documents are what we need.

If you only look at the first request, you will find the title of Yamashita Eiko and can not find, so you also need the following specification details of the request. But this request below will also be included into the store information, and map information carousel.

OK, the data have, due to taking into account the various problems, I did not use the network request, so I will save the data into a.Json file, the subsequent use of delay to imitate the network request.

So there are a few documents.

I'll tell you what I know (MVVM) (iOS)
Paste_Image.png

These JSON we have just caught in the inside, we can look at. What? You ask how I know, I do not know, I am also a try.

The second step, UI analysis

With the data, then analyze the interface. First of all,
is certainly a few

  • Carousel
  • Commodity introduction
  • Price
  • Selected
  • address
  • The smallest label

I cut a relatively complete picture

I'll tell you what I know (MVVM) (iOS)
Paste_Image.png

In other words

  • discount
  • Coupon
  • Promotion
  • author
  • Press
  • Electronic

These are based on data

Third step interface structure

OK, the next is to build a more complex view. Here I will not introduce one, we can go to GitHub to look at my.

First to analyze the Views directory

I'll tell you what I know (MVVM) (iOS)
Paste_Image.png

Tell me about the two places where I’ve been around for a long time.

1 is a promotion, let me tangled for a long time, if the use of tableview is too complicated, how to use other ways to achieve adaptive it?
so I use the characteristics of the Masonry, according to the data using the for loop to create multiple label, and then update the self Masonry, set the lastview distance of self -15 is like this.

I'll tell you what I know (MVVM) (iOS)
Paste_Image.png

2 is the last of these small labels how to display, use collectionView? Feeling too much trouble, and finally found that can be achieved through NSAttributedString.

This problem seems to be solved.

The fourth step is the data analysis

We first create Model, Model I recommend that we use the ESJSONFormat third party plug-ins. Can quickly create Models, easy to use. It would have been like a screenshot, but found that the screenshot looks like a problem, then I’ll just send a screenshot of the directory.

I'll tell you what I know (MVVM) (iOS)
Paste_Image.png

Each class is generated in the style of ESJSONFormat, did not do a lot of changes, but each class of.M with the addition of setValue forUndefinedKey this method, to prevent the development of the data key.

View also has a Model also, in fact, we will find that in MVVM View and Model is basically no change, the focus is on the new addition of ViewModel and the change between Controller.

The fifth step, let us look at our lovely ViewModel

First of all, it should be clear that the ViewModel is in the Controller data processing is extracted to simplify the complexity of Controller, so I understand, from the request to begin in ViewModel, so we need to simulate a network request.

I'll tell you what I know (MVVM) (iOS)
Paste_Image.png
- (RACSignal *) setupModel{@weakify (self); return [RACSignal (createSignal:^RACDisposable * id< RACSubscriber> subscriber) {@strongify (self); [[RACSignal combineLatest:@[[self setupDescModel], [self setupAuthorModel], [self setupCommentModel], [self setupCouponModel], [self setupRecommendModel]]] subscribeNext:^ (ID x) {[self rebackDescModel]; [self rebackCommentModel]; [self rebackRecommendModel]; [self rebackShopModel]; RACTuple = *tuple [RACTuple @ tupleWithObjects: ([self rebackType]), nil]; [subscriber sendNext:tuple]; return nil;}];}];}

SetupModel is our external interface, Controller by calling the setupModel method to send network requests. Because there are multiple requests, so it uses the combineLatest method to monitor all of the requests are completed, the method of reBack, this method is… Again analysis of the data, only need to decompose the needed data interface.

Below we take ProductSkuModel as an example, look at each Model request process:

I'll tell you what I know (MVVM) (iOS)
Paste_Image.png
- (RACSignal *) setupDescModel{return [RACSignal * createSignal:^RACDisposable (id< RACSubscriber> subscriber) {[[RACScheduler mainThreadScheduler]afterDelay:0.5 = [self schedule:^{NSDictionary *dic readJsonFile:@ "ProductDetailModel.json"]; self.productInfo [Wareinfo mj_objectWithKeyValues:dic[@ = "wareInfo" [subscriber sendNext:@ ";" 1 "]; [subscriber sendCompleted]; return [RACDisposable disposableWithBlock:^{}];}];}];}

We need to analyze this method

  • Return value: is a RACSignal, signal as the core of RAC, there is not much explanation.
  • Parameters: because we do not achieve a real network request, there is no parameter, if the real project may need to be introduced into the itemId, etc..
  • Content: we use the [[RACScheduler mainThreadScheduler]afterDelay:0.5 schedule:^{}]; to delay processing (using RAC reinforcement), you can also use dispatch sleep to delay, the same effect.
    and then read the file through the method of reading the file, because it is JSON so saved in dic.
    use MJExtension to parse the JSON, you can go to the GitHub search. After
    we need to resolve the completed data into self.productInfo, call sendNext to send signals

Why not directly to the analytical data directly out of send, considering the main reason is that, we will find that we will have a number of network requests, we need all the network request after the request to the unified data processing, and we do not know which one will first request end. Secondly, the use of RAC combineLatest method in the decomposition of ID x will be more complex, so here we save directly to the self.

Because you need to get the data, and then create the interface in accordance with the data, which shows, which does not show, so here we use enumeration, look like this.

I'll tell you what I know (MVVM) (iOS)
Paste_Image.png

Small screen, please understand.

Typedef enum: NSUInteger < {PRODUCTVIEWTYPENONE = 1; < / * * * * PRODUCTVIEWTYPEWITHSELF= - 0, 1 < 1 < / * * * *, the global purchase PRODUCTVIEWTYPEWITHGLOBAL = 1 < < 2, whether the ad / PRODUCTVIEWTYPEWITHAD / * * * < = 1; < / * * * * / discount 3, PRODUCTVIEWTYPEDISCOUNT = 1 < 4; < / * * * * PRODUCTVIEWTYPEMPRICE, the original < = 1; < 5, PRODUCTVIEWTYPEPROMOTION = 1 * / / * * * promotion < < / * * * * / 6 coupons PRODUCTVIEWTYPECOUPON = 1 < < 7; / * * * *, the author PRODUCTVIEWTYPEAUTHOR < = 1; < 8, PRODUCTVIEWTYPEPRESS = 1 * / / * * *. < < 9,} PRODUCTVIEWTYPE;

Secondly, said a more embarrassing point, I did not find the self and the global purchase of flag. So the program is not running.

So there’s a way in our ViewModel. According to the data if there is a need to display the “or” to type.

I'll tell you what I know (MVVM) (iOS)
Paste_Image.png

In setupModel this type of sendNext will go out.

I'll tell you what I know (MVVM) (iOS)
Paste_Image.png

Why do you want to use tuple it, mainly to consider whether to talk about other data together with the return of the past, and then found that if the return of the past belong to the assignment, and the lack of ViewModel and View binding. So here’s just back to type.

The next is a key place, the data processing and binding.

We give an example of a commercial advertisement.

I'll tell you what I know (MVVM) (iOS)
Paste_Image.png
Set *adAttributStr = nil / / ad NSMutableAttributedString; if (self.productInfo.ad.adword.length! = 0) {adAttributStr = [[NSMutableAttributedString alloc]initWithString:self.productInfo.ad.adword]; NSRange range = [self.productInfo.ad.adword rangeOfString:self.productInfo.ad.adLinkContent]; [adAttributStr addAttribute:NSLinkAttributeName value:[NSURL URLWithString:self.productInfo.ad.adLink] range:range]; / / advertising price assignment self.ad = adAttributStr;}

First of all, according to the length of the Adword to determine whether there is advertising, if we will further processing. Let’s look at the data.

I'll tell you what I know (MVVM) (iOS)
Paste_Image.png

The advertising content in Adword, the link is adLinkContent, link in adLink, this is a link with string, so we use the Adword assignment to NSMutableAttributedString, then get to the Adword adLinkContent in range, NSLinkAttributeName is used in range to link.

Here we have completed the data processing, if not applicable to ViewModel, the code we need to write in Controller, Controller is also a lot of complex.

We need to finish it in.H.

I'll tell you what I know (MVVM) (iOS)
Paste_Image.png

So ViewModel’s work is finished.

Next, you need to go back to the Controller inside, use RACObserve to monitor each of our ViewModel value, the use of RAC to assign to the View in the control of the property valuation can be.

I'll tell you what I know (MVVM) (iOS)
Paste_Image.png

So we assign the ad to ViewModel, it will be monitored, and then assigned to the adLb attributedText attribute.

After the treatment of our Controller code has not been a hundred lines.

I'll tell you what I know (MVVM) (iOS)
Paste_Image.png

OK, I know so much, if there is a better way to welcome the exchange.

Written in the end, if the data is very chaotic, not a commodity, do not panic, in order to test some things, so the data made a mess, but fortunately does not affect the project. In the last, inside the project will see why the carousel figure is not displayed, so, this thing, I went for a long time, finally found a picture because the webp problem, and this problem I want to use SDWebImage SDWebImage/WebP to solve the network, unfortunately, suck, suggest the following questions.

[Error] [libwebp! Installing! Clone https://chromium.googlesource.com/webm/libwebp /var/folders/qc/115mp6bj7hq0wjrmyqvhsvqm0000gn/T/d20170331-5309-1tf8x8d --single-branch --depth /usr/bin/git v0.5.0 Cloning into'/var/folders/qc/ 1 --branch 115mp6bj7hq0wjrmyqvhsvqm0000gn/T/d20170331-5309-1tf8x8d'fatal: unable to access...'https://chromium.googlesource.com/webm/libwebp/' to connect to chromium.googlesource.com: Failed port 443: Operation timed out

We do not worry, I will come back after the update, I will come back!

The reference link (which is the real God:

https://www.raywenderlich.com/74106/mvvm-tutorial-with-reactivecocoa-part-1
) http://blog.leichunfeng.com/blog/2016/02/27/mvvm-with-reactivecocoa/ http:// blog.leichunfeng.com/blog/2015/12/25/reactivecocoa-v2-dot-5-yuan-ma-jie-xi-zhi-jia-gou-zong-lan/
http://blog.devtang.com/2015/11/02/mvc-and-mvvm/
http://www.cocoachina.com/ios/20170213/18659.html

GitHub address: https://github.com/hzj7510/MVVM_JD
blog address: http://hezhengjian.com