Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
iOS ÒÆ¶¯¶Ë¼Ü¹¹³õ̽ÐĵÃ
 
  2414  次浏览      28
 2017-12-8 
 
±à¼­ÍƼö:
±¾ÎÄÀ´×ÔÓÚ²©¿Í¾ò½ð£¬ÕâÆªÎÄÕÂÖ÷ÒªÏêϸÐðÊöÁËÕâ¸ö¼Ü¹¹¹¤¾ßµÄÉè¼ÆË¼Â·ÒÔ¼°Ò»²½²½µÄÓÅ»¯, ÈçºÎ¿ª·¢³öÊʺÏ×Ô¼ºµÄͨÓüܹ¹Éè¼Æ.

Éè¼ÆË¼Â·

¶ÔÓڼܹ¹, ÒÆ¶¯¶Ë³£¼ûµÄ¼Ü¹¹Éè¼Æ°üÀ¨MVC, MVVM, MVPµÈ, ÉÏͼ¼òÒªµÄ˵Ã÷Á˸÷ÖÖ³£¼ûµÄ¼Ü¹¹Ö®¼äµÄ½»»¥¼°Êý¾Ý´«µÝ·½Ê½.

¶ÔÓÚMVC, MVVM, MVPÕâÈýÖּܹ¹Éè¼ÆÄ£Ê½, ÏàÐÅ´ó¼ÒÒ»¶¨ÁËÈ»ÓÚÐÄ, Ïà¹ØµÄÎÄÕÂÒ²ÊǶàÈç·±ÐÇ, ¶ÔÓÚÕâЩ³£Óüܹ¹, ÿ¸öÈ˶¼¿Ï¶¨ÓÐÿ¸öÈ˵ÄÀí½â, µ«ÕâÑù»áµ¼ÖÂÒ»¸öÎÊÌâ, ¾ÍÊǼ«´óµÄ×ÔÓɶȵ¼ÖÂÁËûÓдúÂë¹æ·¶, ¶ÔÓÚÒÆ¶¯¶Ë»òÕßǰ¶Ë¼°ºó¶ËÀ´Ëµ, Æä±¾Öʹ¤×÷¾ÍÊÇÊý¾Ý²ãºÍչʾ²ãµÄ½»»¥, ÈçºÎ½«Êý¾ÝÕýÈ·°²È«¸ßЧµÄ´«Ê䵽չʾ²ã.

ÕâÀïµÄÊý¾Ý²ã´ÓÕû¸öÏîÄ¿À´Ëµ, ¿ÉÒÔ˵ÊǺó¶Ë, Ò²¾ÍÊÇ·þÎñ¶Ë, ¶ÔÓÚ·þÎñ¶Ë¿ª·¢µÄÁ÷³Ì¾ÍÊÇ´ÓÊý¾Ý¿â»ñÈ¡Êý¾Ý²¢½«Êý¾Ý½øÐи÷ÖÖÂß¼­¹ýÂË×÷ΪÏìÓ¦·µ»Ø¸øÇ°¶ËÓÃÓÚչʾ²ãչʾ, ¶ÔÓÚjavaΪÀý, ÎÒÃÇÆÕͨµÄÏîÄ¿¾Í»á·ÖΪcontroller, service, dao, pojo, vo, boµÈ²ã¼¶Éè¼Æ, ¾Í»á½«²»Í¬¹¦ÄܽøÐгéÏó, ʹµÃ´úÂë¸üÈÝÒ×ά»¤.

¶ø×÷Ϊչʾ²ãµÄǰ¶Ë, Ò²¾ÍÊǿͻ§¶Ë, ÆäÊµÒÆ¶¯¶ËÔÚÎҸоõÆäʵҲÊÇǰ¶ËµÄÒ»¸ö·ÖÖ§, ¶øÇ°¶ËµÄ¼Ü¹¹Í¨³£Îª×é¼þ»¯Éè¼Æ, ÿһ¸ö¹¦ÄÜview¶ÔÓ¦Ò»¸ö×é¼þ, ¶øÕû¸öÒ³Ãæ¿ÉÒÔͨ¹ý¶à¸ö×é¼þ·ÖÀë½øÐÐά»¤, ºÜ¸ßЧµÄ½«ÒµÎñ´úÂëºÍÊÓͼ½øÐзÖÀë, ʹµÃ´úÂë¸üÓй淶¼°Ò×ά»¤.

¶ø¶ÔÓÚÒÆ¶¯¶Ë, ΪʲôҪÔÚcontrollerÖÐдÄÇô¶à²»ÖªËùÔÆµÄ´úÂë? Ϊʲôһ¸ö¿ØÖÆÆ÷Äܳ¬¹ý1kÐÐ? ΪʲôviewµÄÂß¼­»Øµ÷´úÀíҪдÔÚcontrollerÖÐ? Ϊʲô¿ØÖÆÆ÷Ö®¼äµÄ²ÎÊý´«µÝµÄñîºÏÐÔÄÇôǿ? ÎªÊ²Ã´ÍøÂçÇëÇóµÄ·½·¨Ëæ´¦¿É¼û? ΪʲôÎÒÃDz»Äܹ»Ïñǰºó¶ËÄÇÑùÓÐÌõÀíµÄ¿ØÖÆÎÒÃǵĴúÂë? ¶øÈÃÆäÏñÍÑçÖµÄÒ°ÂíÄÑÒÔ¼ÝÔ¦ÄØ?

ΪÁ˽â¾öÕâЩÎÊÌâ, ÎÒÃÇÐèÒª¿¼ÂÇһЩ¼Ü¹¹Éè¼ÆÄ£Ê½, ×îÏÈÏëµ½µÄ¾ÍÊÇÒÔcontrollerΪÖÐÐĵijéÏó, ½«¿ØÖÆÆ÷µÄ¹¦ÄܳéÏ󵽸þßÌ帺ÔðµÄÄ£¿é, ´ÓͼÉÏ¿ÉÒÔ¿´µ½, controllerά»¤ÁËpresenter, viewmodel, view, ¶øviewmodelÓÖά»¤ÁËmodel, ÆäÖеÄmodelÒ²¿ÉÒÔ˵¾ÍÊÇjavabeanÍêÈ«µÄ´¿Êý¾Ý½á¹¹, viewmodelÊÇmodelµÄÉÏÒ»²ã, ÓÃÓÚ²Ù×÷¶ÔÓ¦µÄÊý¾Ý, ¿ÉÒÔ¿´µ½controller½«´úÂëÏ·¢ÖÁÏÂÃæÈý²ã, ʹµÃ¸÷¸ö²ã¼¶¸÷˾ÆäÖ°.

¸Õ²ÅÊÇÕ¾ÔÚcontrollerµÄÊÓ½ÇÉÏÀ´¿´µÄ, ¶ÔÓÚÊý¾ÝµÄ´«Êä, Õâ´ÎÎÒÃÇÕ¾ÔÚpresenterµÄÊÓ½ÇÉÏÀ´¿´, Õâ¸öÉè¼Æ¾ÍÊǽ«viewmodel×÷Ϊ´«µÝ¶ÔÏóͨ¹ýpresenterÕâ¸öÖмä¼þ´«ÊäÖÁview²ã, ÕâÑùview²ã²»½ö¿ÉÒÔÄõ½Êý¾Ý, Ò²¿ÉÒÔ¶ÔÊý¾Ý½øÐвÙ×÷, ÕÆ¿ØÐÔÓÐËùÌá¸ß.

¸Õ²ÅÎÒÃÇÕ¾ÔÚÁËcontrollerºÍpresenterÊÓ½ÇÉÏ·ÖÎöÁ˼ܹ¹Éè¼ÆµÄ˼·, µ«ÕâÑù¸÷¸ö²ã¼¶µÄñîºÏ»áÔ½À´Ô½´ó, ´Ó¶øµ¼ÖÂÏîÄ¿´úÂëÎÞ·¨·Ö¸î, ÕâʱÏëµ½Á˺ó¶ËcontrollerºÍserviceÖ®¼äͨ¹ý½Ó¿Ú½øÐн»»¥À´½µµÍñîºÏ, ÎÒÃÇÊDz»ÊÇÒ²¿ÉÒԲο¼ÕâÖÖ·½°¸Í¨¹ýÒ»¸öprotocolÎĵµÎļþÀ´½µµÍ¸÷¸ö²ã¼¶Ö®¼äµÄñîºÏÄØ, ÈçͼËùʾ, ½«³ýÁËcontrollerÖ®ÍâµÄÆäËû²ã¼¶½øÐнâñî. ½øÐи߶ȳéÏó.

ÉÏÃæÎÒÃǽâ¾öÁ˸÷¸ö²ã¼¶Ö®¼äµÄñîºÏ, µ«ÎÒÃÇÔõô½â¾ö¿ØÖÆÆ÷Ö®¼äµÄñîºÏÄØ? ´ð°¸ÊÇrouter, ÎÒÃÇÕ¾ÔÚ·ÓɵÄÊÓ½ÇÉÏ¿´, ¸÷´ó¿ØÖÆÆ÷¶¼ÊǶÀÁ¢´æÔڵĸöÌå, ±Ë´ËÖ®¼äµÄ½»»¥Í¨¹ý·ÓɵÄÓ³Éä½øÐн»»¥, ÕâÑùÎÒÃǾÍÄܹ»È¥³ý¸÷´ó¿ØÖÆÆ÷Ö®¼äµÄñîºÏÁË. ·ÓÉÕâ¸ö˼·×îÏÈÒ²ÊÇÔÚǰ¶ËµÄ¼Ü¹¹¿ò¼ÜÖп´µ½µÄ, ºóÀ´¾ÍÓÐÁËcocoapods˽Óпâ×é¼þ»¯ÕâÖÖ¼¯³É»¯µÄ½â¾ö·½°¸, ͨ¹ý·ÓÉÓ³ÉäÄܹ»ºÜºÃµÄ×öµ½Ä£¿é·ÖÀë, ¸ü¿ÉÒÔ×öµ½Ò³Ãæ½µ¼¶, ËùνµÄÒ³Ãæ½µ¼¶¾ÍÊÇÖ¸²»½ö·ÓÉ¿ÉÒÔºÍnative½øÐн»»¥, Ò²¿ÉÒÔºÍh5½øÐн»»¥, µ±nativeºÍh5ÊÇÒ»Ì×ÒµÎñÂß¼­µÄʱºò, native²»É÷³öÏÖbugÎÒÃÇ¿ÉÒÔÇëÇóºó¶Ë½Ó¿ÚÐÞ¸ÄÊý¾Ý¿â½«Ò³ÃæÖ±½Ó½µ¼¶ÖÁh5Ò³Ãæ¶ø²»ÓÃÖØÐ´ò°üµÈ´ýÆ»¹ûÉóºË¼°Ê¹ÓÃÈÈÐÞ¸´¹¤¾ß´øÀ´ÁËʱ¼äÏûºÄ. Äܹ»µÚһʱ¼ä½â¾öÎÊÌâ.

½â¾öÁËÉÏÊöÎÊÌâ, ÎÒÃǾÍֻʣÏÂÒ³ÃæµÄÎÊÌâÁË, ¶ÔÓÚÏÖÔÚµÄiOSerÀ´Ëµ, Ð´Ò³Ãæ¼¸ºõÊÇÈÕ³£¹¤×÷µÄ¾ø´ó²¿·Ö, µ«ÊÇÐ´Ò³Ãæ, дҵÎñ, µ±Âß¼­¸´ÔÓµÄʱºòÒ²»á²úÉúһϵÁв»Ò×ά»¤µÄÎÊÌâ, ÕâʱºòÎÒÃǾͿÉÒÔʹÓÃÀàËÆreduxÕâÖÖ״̬»úµÄģʽ, ½«ÒµÎñÂß¼­²ð·Ö³ö²»Í¬¸´ÔÓµÄ״̬, µ±±äÁ¿¸Ä±äµÄʱºò, ´¥·¢²»Í¬µÄ״̬, ÕâÑù¾ÍÄܹ»ÓÐЧµÄ¹ÜÀíÎÒÃǵÄÒ³ÃæÂß¼­. ÍÆ¼ö¿ÉÒÔ¿´¿´reactºÍreduxµÄ˼·, ¶ÔÕâ¿éÒ²»áÓиüºÃµÄÕÆÎÕ.

Éè¼ÆË¼Â·µÄ×ܽá¾ÍÊÇ, ͨ¹ý¸ß¶È³éÏó½øÐзֲã, ͨ¹ý½Ó¿ÚÎĵµ½øÐÐÏîÄ¿²ã¼¶½âñî, ͨ¹ý·ÓɽøÐÐ×é¼þ»¯¼°½µ¼¶, ͨ¹ýCDDģʽ¹á´©subviewʹµÃËùÓеÄview¶¼Äܹ»Äõ½Êý¾Ý¼°²Ù¿ØÊý¾Ý, ͨ¹ýAOPÇÐÃæ½øÐÐhookÒ»Ð©ÌØÊ⹦ÄÜÈçÂñµãͳ¼Æ, È«¾Öµ±Ç°¿ØÖÆÆ÷µÈµÈ.

Éè¼ÆÊµÏÖÉÏÃæ²¿·Ö, ÐðÊöÁËÕû¸ö¼Ü¹¹µÄÉè¼ÆË¼Â·, ½ÓÏÂÀ´, ÎÒÃÇÀ´¿´¿´ÈçºÎ¾ßÌåʵÏÖ. ÒÔÏ´úÂëÈ¡×ÔÕæÊµÏîÄ¿, ¶ÔÓ¦viewÊÓ½ÇͼÖеÄÉè¼ÆÍ¼.

//
// InterfaceTemplate.h
// SQTemplate
//
// Created by ˫Ȫ Öì on 17/5/5.
// Copyright ? 2017Äê Doubles_Z. All rights reserved.
//
#import <UIKit/UIKit.h>
@protocol HYAbroadShoppingHomeModelInterface <NSObject>
/**
* ½öÓÃÀ´±£³ÖPB²»Îª¿Õ
*/
@property(nonatomic) NSInteger status ;
/**
* ¹ã¸æÎ»
*/
@property(nonatomic,strong) NSMutableArray * banners ;
/**
* Ëĸöicon
*/
@property(nonatomic,strong) NSMutableArray * shortCutIcons ;
/**
* ´ÙÏúʱ¼ä´Á£¬»î¶¯Ê£Óàʱ¼ä,ת»»³ÉºÁÃë
*/
@property(nonatomic,strong) NSString * remainingTime ;
/**
* µ¹¼ÆÊ±µÄÉÌÆ·£¬¿Í»§¶Ë¸ù¾Ýµ±¸Ã×Ö¶ÎÓеÄʱºò£¬Õ¹Ê¾¡°½ñÈÕ¶çÊÖ¼Û¡±Í¼Æ¬
*/
@property(nonatomic,strong) NSMutableArray * salesGoods ;
/**
* È«Çò¾«Ñ¡ÉÌÆ·¼¯ºÏ
*/
@property(nonatomic,strong) NSMutableArray * selectGoods ;
@property (nonatomic,assign,getter=isLoaded) BOOL loaded;
@property (nonatomic,assign,getter=isReload) BOOL reload;
@end
@protocol HYAbroadShoppingHomeViewModelInterface <NSObject>
@optional
@property (nonatomic,strong) id<HYAbroadShoppingHomeModelInterface> model;
@optional
- (void)initializeWithModel:(id<HYAbroadShoppingHomeModelInterface>)model completion:(void(^)())completion;
/**
*Á¢¼´¹ºÂò
* @para goodsId ÕâÀïAndroid¾ÍÈ¥µ÷ÓÃCommonUtilsÀïÃæµÄ·½·¨¼´¿É¡£IOSÕâÀï×ÔÐÐÌí¼ÓÏàÓ¦µÄ´úÂë¡£×¢ÒâÕâÀï±£³ÖÒ»¸öÂß¼­£ºÈç¹ûÊÇ´¦·½Ò©½øÈëµ½ÉÌÆ·ÏêÇéÒ³£¬ÒþÐÎÑÛ¾µ¡­..
*/
- (void)senderAddShoppingCartWithModel:(id<HYAbroadShoppingHomeModelInterface>)model goodsId:(GoodsID *)goodsId completion:(void(^)())completion;
/**
*»ñÈ¡º£Í⹺Ê×Ò³
*/
- (void)senderAbroadShoppingHomeWithModel:(id<HYAbroadShoppingHomeModelInterface>)model completion:(void(^)())completion;
@end
@protocol HYAbroadShoppingHomeViewInterface <NSObject>
@property (nonatomic,strong) id<HYAbroadShoppingHomeViewModelInterface> abroadshoppinghomeViewModel;
@property (nonatomic,strong) id<HYAbroadShoppingHomeViewModelInterface> abroadshoppinghomeOperator;
@end

½Ó¿ÚÎĵµÎļþ½«Õû¸öÒ³ÃæÄ£¿é·Ö³ÉÁËModelInterface, ViewModelInterface, ViewInterfaceÈý¸ö½Ó¿Ú,ModelInterface½Ó¿Ú¶ÔÓ¦ÁË·þÎñÆ÷·µ»ØµÄÍâ²ãÊý¾Ý½á¹¹, ViewModelInterface½Ó¿Ú¶ÔÓ¦Á˲Ù×÷modelÊý¾ÝµÄ·½·¨, Èç·¢ÆðÇëÇóºÍ´ÓÊý¾Ý¿â¶ÁÈ¡ÖîÈç´ËÀà. ViewInterfaceÓµÓÐÁ½ÕßµÄÄÜÁ¦.

//
// ControllerTemplate.m
// SQTemplate
//
// Created by ˫Ȫ Öì on 17/5/5.
// Copyright ? 2017Äê Doubles_Z. All rights reserved.
//
#import "HYAbroadShoppingHomeViewController.h"
#import "HYAbroadShoppingHomePresenter.h"
#import "HYAbroadShoppingHomeViewModel.h"
#import "HYAbroadShoppingHomeView.h"
@interface HYAbroadShoppingHomeViewController ()
@property (nonatomic,strong) HYAbroadShoppingHomePresenter * abroadshoppinghomePresenter;
@property (nonatomic,strong) HYAbroadShoppingHomeViewModel * abroadshoppinghomeViewModel;
@property (nonatomic,strong) HYAbroadShoppingHomeView * abroadshoppinghomeView;
@end
@implementation HYAbroadShoppingHomeViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"È«Çò¹º";
[self setupView];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self adapterView];
}
- (HYAbroadShoppingHomePresenter *)abroadshoppinghome

Presenter {
if (!_abroadshoppinghomePresenter) {
_abroadshoppinghomePresenter = [HYAbroadShopping

HomePresenter new];
}
return _abroadshoppinghomePresenter;
}
- (HYAbroadShoppingHomeViewModel *)abroadshopp

inghomeViewModel {
if (!_abroadshoppinghomeViewModel) {
_abroadshoppinghomeViewModel = [HYAbroadShopping

HomeViewModel new];
}
return _abroadshoppinghomeViewModel;
}
- (HYAbroadShoppingHomeView *)abroadshoppinghome

View {
if (!_abroadshoppinghomeView) {
_abroadshoppinghomeView = [HYAbroadShoppingHome

View new];
_abroadshoppinghomeView.frame = self.view.bounds;
}
return _abroadshoppinghomeView;
}
- (void)setupView {
[self.view addSubview:self.abroadshoppinghomeView];
}
- (void)adapterView {
[self.abroadshoppinghomePresenter adapterWithAbroadShoppingHomeView:self.abroad

shoppinghomeView abroadshoppinghomeViewModel

:self.abroadshopping

homeViewModel];
}
@end

¾­¹ý³éÏóºó, ÎÒÃÇÔÙÀ´¿´¿´controllerµÄÎļþ, ÎÒÃÇ¿ÉÒÔ¿´µ½, ¾­¹ý³éÏóºóµÄ¿ØÖÆÆ÷¼ÓÉ϶¥²¿µÄ×¢ÊÍÒ²Ö»ÓÐ68ÐÐ, »ù±¾ÊDz»ÓÃÔÙÓÃÐÄά»¤ÉÏǧÐеĿØÖÆÆ÷ÁË.

//
// PresenterTemplate.m
// SQTemplate
//
// Created by ˫Ȫ Öì on 17/5/5.
// Copyright ? 2017Äê Doubles_Z. All rights reserved.
//
#import "HYAbroadShoppingHomePresenter.h"
@interface HYAbroadShoppingHomePresenter ()
@property (nonatomic,weak) id<HYAbroadShoppingHome

ViewInterface>

abroadshoppinghomeView;
@property (nonatomic,weak) id<HYAbroadShoppingHome

ViewModelInterface>

abroadshoppinghomeViewModel;
@end
@implementation HYAbroadShoppingHomePresenter
- (void)adapterWithAbroadShoppingHomeView:

(id<HYAbroadShoppingHome

ViewInterface>)abroadshoppinghomeView abroadshop

pinghomeViewModel:

(id<HYAbroadShoppingHomeViewModel

Interface>)abroadshoppinghomeViewModel {
_abroadshoppinghomeView = abroadshoppinghomeView;
_abroadshoppinghomeViewModel = abroadshoppinghomeViewModel;
__weak typeof(self) _self = self;
__weak id<HYAbroadShoppingHomeViewModelInterface> __abr

oadshoppinghomeViewModel = _abroadshoppinghomeViewModel;
[_abroadshoppinghomeViewModel initializeWithModel:

__abroadshopping

homeViewModel.model completion:^{
_self.abroadshoppinghomeView.abroadshoppinghomeViewModel = __

abroadshoppinghomeViewModel;
_self.abroadshoppinghomeView.abroadshoppinghomeOperator = _self;
}];
}
/**
*Á¢¼´¹ºÂò
* @para goodsId ÕâÀïAndroid¾ÍÈ¥µ÷ÓÃCommonUtilsÀïÃæµÄ·½·¨¼´¿É¡£

IOSÕâÀï×ÔÐÐÌí¼ÓÏàÓ¦µÄ´úÂë¡£×¢ÒâÕâÀï±£³ÖÒ»¸öÂß¼­£ºÈç¹ûÊÇ´¦·½Ò©

½øÈëµ½ÉÌÆ·ÏêÇéÒ³£¬ÒþÐÎÑÛ¾µ¡­..
*/
- (void)senderAddShoppingCartWithModel:(id<HYAbroadShoppingHome

ModelInterface>)model goodsId:(GoodsID *)goodsId completion:

(void(^)())completion {
__weak typeof(self) _self = self;
__weak id<HYAbroadShoppingHomeViewModelInterface> __abroad

shoppinghomeViewModel = _abroadshoppinghomeViewModel;
[_abroadshoppinghomeViewModel senderAddShoppingCartWithModel:model

goodsId:goodsId completion:^{
_self.abroadshoppinghomeView.abroadshoppinghomeViewModel = __

abroadshoppinghomeViewModel;
completion();
}];
}
/**
*»ñÈ¡º£Í⹺Ê×Ò³
*/
- (void)senderAbroadShoppingHomeWithModel:(id<HY

AbroadShoppingHome

ModelInterface>)model completion:(void(^)())completion {
__weak typeof(self) _self = self;
__weak id<HYAbroadShoppingHomeViewModelInterface>

__abroadshopping

homeViewModel = _abroadshoppinghomeViewModel;
[_abroadshoppinghomeViewModel senderAbroadShoppin

gHomeWithModel:model

completion:^{
_self.abroadshoppinghomeView.abroadshoppinghome

ViewModel = __abroadshop

pinghomeViewModel;
completion();
}];
}

ÔÚcontrollerÖÐ, ÎÒÃǽ«viewmodelºÍview, Ò²¾ÍÊÇÉÏÊöµÄÊý¾Ý²ãºÍչʾ²ã´«Êäµ½ presenterµÄÖмä¼þ½øÐн»»¥, ÎÒÃÇͨ¹ý¹Û²ì¿ÉÒÔ¿´µ½µ±ÇëÇóÍê³Éºó, ÏȽøÐи³Öµ²Ù×÷, ÔÙ½øÐÐ×Ô¶¨ÒåÒµÎñÂß¼­, ÕâÑùÄܹ»±£Ö¤²Ù×÷ÒµÎñÂß¼­Ê±Êý¾ÝÊÇ×îеÄ.

//
// ViewModelTemplate.m
// SQTemplate
//
// Created by ˫Ȫ Öì on 17/5/5.
// Copyright ? 2017Äê Doubles_Z. All rights reserved.
//
#import "HYAbroadShoppingHomeViewModel.h"
#import "HYAbroadShoppingHomeModel.h"
#import "HYAbroadShoppingSender.h"
#import "HYMallGoodsSender.h"
@implementation HYAbroadShoppingHomeViewModel
- (HYAbroadShoppingHomeModel *)model {
if (!_model) {
_model = [HYAbroadShoppingHomeModel new];
}
return _model;
}
- (void)initializeWithModel:(id<HYAbroadShoppingHomeMode

lInterface>)model completion:(void(^)())completion {
if (!model.isLoaded) {
[self senderAbroadShoppingHomeWithModel:model completion:

completion];
}
}
/**
*Á¢¼´¹ºÂò
* @para goodsId ÕâÀïAndroid¾ÍÈ¥µ÷ÓÃCommonUtilsÀïÃæµÄ·½·¨¼´¿É¡£

IOSÕâÀï×ÔÐÐÌí¼ÓÏàÓ¦µÄ´úÂë¡£×¢ÒâÕâÀï±£³ÖÒ»¸öÂß¼­£ºÈç¹ûÊÇ´¦·½Ò©

½øÈëµ½ÉÌÆ·ÏêÇéÒ³£¬ÒþÐÎÑÛ¾µ¡­..
*/
- (void)senderAddShoppingCartWithModel:(id<HYAbroadShoppingHome

ModelInterface>)model goodsId:(GoodsID *)goodsId completion:

(void(^)())completion {
NSMutableArray * editArray=[@[] mutableCopy];
EditGoodsM_Builder * editGoodsM_Builder=[[EditGoodsM_Builder

alloc]init];
editGoodsM_Builder.goodsId = goodsId;
editGoodsM_Builder.amount = 1;
[editArray addObject:[editGoodsM_Builder build]];
HYSenderResultModel * resultModel = [HYMallGoodsSender

senderAddShoppingCart:nil token:nil editGoods:editArray

promoteIDs:nil];
HYViewController * vc = [HYCurrentVCmanager shareInstance].

getCurrentVC;
[vc startLoading];
[vc requestWithModel:resultModel success:^(HYResponseModel

*model) {
_model.reload = NO;


completion();
[vc endLoading];
} failure:^(HYResponseModel * model) {
[vc endLoading];
}];
}
/**
*»ñÈ¡º£Í⹺Ê×Ò³
*/
- (void)senderAbroadShoppingHomeWithModel:(id<HYAbroadShopping

HomeModelInterface>)model completion:(void(^)())completion {
HYSenderResultModel * resultModel = [HYAbroadShoppingSender senderAbroadShoppingHome:model status:0];
HYViewController * vc = [HYCurrentVCmanager shareInstance].

getCurrentVC;
[vc startLoading];
[vc requestWithModel:resultModel success:^(HYResponseModel

*model) {
_model.loaded = YES;
completion();
[vc endLoading];
} failure:^(HYResponseModel * model) {
[vc endLoading];
}];
}

ÎÒÃÇÔÙÀ´¿´¿´viewmodel²ãÈçºÎÉè¼Æ, viewmodel²ã³ÖÓÐmodel, ²¢½øÐÐÊý¾Ý»ñÈ¡, ½«»ñÈ¡µÄÊý¾Ý¸³Öµµ½modelÖÐ, ÓÉÓÚÏßÉÏÕæÊµÏîĿʹÓõÄÊÇTCP+ProtoBuffer, ´úÂëÏÔʾµÄÊÇÎÒ˾×ÔÐзâ×°µÄÒ»Ì×ÍøÂçÂß¼­, ËùÒÔ¿ÉÄܶÔһЩͬѧ²»ÊǺÜÓѺÃ, Çë¿´ÏÂÃæµÄÀý×Ó:

//
// ViewModelTemplate.m
// SQTemplate
//
// Created by ˫Ȫ Öì on 17/5/5.
// Copyright ? 2017Äê Doubles_Z. All rights reserved.
//
#import "ViewModelTemplate.h"
#import "ModelTemplate.h"
#import "NetWork.h"
#import "DataBase.h"
@implementation ViewModelTemplate
- (void)dynamicBindingWithFinishedCallBack:(void (^)())finishCallBack {
[DataBase requestDataWithClass:[ModelTemplate class] finishedCallBack:^(NSDictionary *response) {
_model = [ModelTemplate modelWithDictionary:response];
finishCallBack();
}];
[NetWork requestDataWithType:MethodGetType URLString:@"http://localhost:3001/api/J1/getJ1List"

parameter:nil finishedCallBack:^(NSDictionary *

response){
_model = [ModelTemplate modelWithDictionary:respons

e[@"data"]];
[DataBase cache:[ModelTemplate class] data:respons

e[@"data"]];
finishCallBack();
}];
}

ÆäÖÐDataBase½ö½öÊÇplistµÄ»º´æ, ¶øNetWorkÊÇ·â×°µÄAFNetworking, ÕâÑù´ó²¿·Öͬѧ¾ÍºÜÊìϤÁ˰É, ÔÚviewmodel²ã¿ÉÒÔ½«ÊýÊý¾Ý¿âºÍÍøÂçÇëÇóÕâÁ½ÖÖ»ñÈ¡Êý¾ÝµÄ·½Ê½·â×°ÔÚÒ»¸ö²ã¼¶ÀïÃæ, ÕâÑùÂß¼­·ÖÃ÷Ò²¶ÔÍâ½çûÓÐñîºÏ, ¶ø¶ÔÓÚÎÒÃÇÏßÉÏÏîÄ¿ÎÒÃÇÔڵײ㻹ÓÐÒ»¸ösender²ãÓÃÓÚ¹ÜÀíÉÏÊöÎÊÌ⼰һЩÆäËûÒµÎñÂß¼­, ͨÓõļܹ¹Éè¼ÆÊÇÒ»¸ö˼Ïë, ÐèÒª½áºÏʵ¼ÊÒµÎñÂß¼­½øÐе÷Õû, ÕýËùν²»ÄÜÍÑÀëÒµÎñ̸¼Ü¹¹.

//
// ViewTemplate.m
// SQTemplate
//
// Created by ˫Ȫ Öì on 17/5/5.
// Copyright ? 2017Äê Doubles_Z. All rights reserved.
//
#import "HYAbroadShoppingHomeView.h"
#import "HYAbroadShoppingHomeHeaderView.h"
#import "HYAbroadSelectGoodsViewCell.h"
@interface HYAbroadShoppingHomeView ()

<UITableViewDataSource,

UITableViewDelegate>
@property (nonatomic,strong) UITableView * tableView;
@property (nonatomic,strong) HYAbroadShopping

HomeHeaderView

* headerView;
@end
@implementation HYAbroadShoppingHomeView
- (void)dealloc {
NSLog(@"%@ - execute %s",NSStringFromClass

([self class]),__func__);
}
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self setupSubviews];
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)coder {
self = [super initWithCoder:coder];
if (self) {
[self setupSubviews];
}
return self;
}
- (UITableView *)tableView {
if (!_tableView) {
_tableView = [UITableView new];
_tableView.dataSource = self;
_tableView.delegate = self;
_tableView.tableHeaderView = self.headerView;
_tableView.backgroundColor = SQBGC;
_tableView.separatorStyle = UITableViewCellSe

paratorStyleNone;
}
return _tableView;
}
- (HYAbroadShoppingHomeHeaderView *)headerView {
if (!_headerView) {
_headerView = [HYAbroadShoppingHomeHeaderView new];
_headerView.hidden = YES;
}
return _headerView;
}
- (void)setupSubviews {
[self addSubview:self.tableView];
}
- (void)setAbroadshoppinghomeViewModel:(id<HYAbroadShoppingHome

ViewModelInterface>)abroadshoppinghomeViewModel {
_abroadshoppinghomeViewModel = abroadshoppinghomeViewModel;
if (abroadshoppinghomeViewModel.model.reload) {
_headerView.hidden = !abroadshoppinghomeViewModel.model.isLoaded;
_headerView.model = abroadshoppinghomeViewModel.model;
CGFloat headerViewH = abroadshoppinghomeViewModel.model.

remainingTime.length
? kscaleDeviceLength(160) + (self.width / 4) * 1.1 + 290
: kscaleDeviceLength(160) + (self.width / 4) * 1.1 + 50;
_headerView.frame = CGRectMake(0, 0, 0, headerViewH);
[_tableView reloadData];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsIn

Section:(NSInteger)section {
return _abroadshoppinghomeViewModel.model.selectGoods.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView

cellForRowAtIndexPath:(NSIndexPath *)indexPath {
HYAbroadSelectGoodsViewCell * cell = [HYAbroadSelectGoods

ViewCell cellWithTableView:tableView];
cell.good = _abroadshoppinghomeViewModel.model.selectGoods

[indexPath.item];
cell.abroadshoppinghomeOperator = _abroadshoppinghomeOperator;
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightFor

RowAtIndexPath:(NSIndexPath *)indexPath {
return [HYAbroadSelectGoodsViewCell cellHeightWithGood:

_abroadshoppinghomeViewModel.model

.selectGoods[indexPath.item]];
}
- (void)tableView:(UITableView *)tableView didSelectRowA

tIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (void)layoutSubviews {
[super layoutSubviews];
_tableView.frame = self.bounds;
}

½Ó×ÅÎÒÃÇÀ´¿´view,¸ù¾Ý֮ǰµÄÉè¼ÆÍ¼, ÎÒÃǽ«ÆäÇø·ÖΪÁ½¸öÄ£¿é, tableviewµÄheaderviewºÍtableviewcell, ÆäÖÐheaderview¸ºÔðÉÏÃæ²»ÐèÒª¸´ÓõÄview, ¶øtableviewcell¸ºÔðÐèÒª¸´ÓõIJ¿·Ö.

ÕâÀïÎÒÃÇ¿´µ½ÖØÐ´set·½·¨Ê±¸ù¾ÝÊÇ·ñÐèҪˢÐÂtableview, Ò»¶¨Ï޶ȱÜÃâÁËÎÞЧµÄË¢ÐÂÏûºÄ.

»¹ÓÐÒ»¸ö֪ʶµãÊǽ«operatorÖ±½Ó¹á´©´«µÝµ½¸÷¼¶subviewÕâÀïÓõ½µÄ¾ÍÊÇCDDģʽµÄ¾«Ëè, ʹµÃËùÓеÄsubview¶¼Äܹ»»ñÈ¡Êý¾Ý, ±ÜÃâÁËdelegate, blockÕâÖÖÈßÓà»Øµ÷´øÀ´ñîºÏµÄÞÏÞÎ, ¹Ø¼üÊdzó.

//
// HYAbroadSelectGoodsViewFrameHub.m
// Mall
//
// Created by Öì˫Ȫ on 19/10/2017.
// Copyright ? 2017 _Zhizi_. All rights reserved.
//
#import "HYAbroadSelectGoodsViewFrameHub.h"
#import "NSString+SQExtension.h"
@implementation HYAbroadSelectGoodsViewFrameHub
- (instancetype)initWithGoodsName:(NSString *)

goodsName nameGoodEvalution:(NSString *)name

GoodEvalution {
self = [super init];
if (self) {
CGFloat width = DeviceWidth - 30;
CGFloat proImageUrlButtonX = 10;
CGFloat proImageUrlButtonY = proImageUrlButtonX;
CGFloat proImageUrlButtonW = width - 2 * pro

ImageUrlButtonX;
CGFloat proImageUrlButtonH = proImageUrlButtonW;
_proImageUrlButtonFrame = CGRectMake(proImage

UrlButtonX, proImageUrlButtonY, proImageUrlButtonW, proImageUrlButtonH);
CGFloat goodsSellerImageViewX = proImageUrlButtonX;
CGFloat goodsSellerImageViewY = proImageUrlButtonY + proImageUrlButtonH + 13;
CGFloat goodsSellerImageViewW = 20;
CGFloat goodsSellerImageViewH = 15;
_goodsSellerImageViewFrame = CGRectMake(goodsSeller

ImageViewX, goodsSellerImageViewY, goods

SellerImageViewW, goodsSellerImageViewH);
CGFloat goodsNameLabelX = goodsSellerImageViewX;
CGFloat goodsNameLabelY = proImageUrlButtonY +

proImageUrlButtonH + 10;
CGFloat goodsNameLabelW = proImageUrlButtonW;
CGSize goodsNameLabelSize = [goodsName getSizeWithConstraint:CGSizeMake(goodsName

LabelW, 60) font:KF03_17];
CGFloat goodsNameLabelH = goodsNameLabelSize.height;
_goodsNameLabelFrame = CGRectMake(goodsNameLabelX, goodsNameLabelY, goodsNameLabelW, goodsNameLabelH);
CGFloat costPriceLabelY = 0.0;
if (nameGoodEvalution.length) {
CGFloat userEvalutionLabelX = proImageUrlButtonX + 10;
CGFloat userEvalutionLabelY = goodsNameLabelY +

goodsNameLabelH + 10;
CGFloat userEvalutionLabelW = 55;
CGFloat userEvalutionLabelH = 20;
_userEvalutionLabelFrame = CGRectMake(userEva

lutionLabelX, userEvalutionLabelY, userEvalutionLabelW,

userEvalutionLabelH);
CGFloat userEvalutionBackgroundX = proImageUrlButtonX;
CGFloat userEvalutionBackgroundY = userEvalutionLabelY + userEvalutionLabelH / 2;
CGFloat userEvalutionBackgroundW = proImageUrlButtonW;
CGFloat nameGoodEvalutionLabelX = userEvalution

BackgroundX+ 10;
CGFloat nameGoodEvalutionLabelY = userEvalutionLabelY + userEvalutionLabelH + 10;
CGFloat nameGoodEvalutionLabelW = userEvalution

BackgroundW - 20;
CGSize nameGoodEvalutionLabelSize = [nameGoodEvalution getSizeWithConstraint:CGSizeMake(nameGoodEvalu

tionLabelW, 40) font:KF06_12];
CGFloat nameGoodEvalutionLabelH = nameGoodEvalutionLabelSize.height;
_nameGoodEvalutionLabelFrame = CGRectMake(nameGoodEvalutionLabelX, nameGood

EvalutionLabelY, nameGoodEvalutionLabelW, nameGoodEvalutionLabelH);
CGFloat userEvalutionBackgroundH = nameGood

EvalutionLabelH + 30;
_userEvalutionBackgroundFrame = CGRectMake(userEvalutionBackgroundX, userEvalutio

nBackgroundY, userEvalutionBackgroundW, userEvalutionBackgroundH);
costPriceLabelY = userEvalutionBackgroundY + userEvalutionBackgroundH + 10;
} else {
costPriceLabelY = goodsNameLabelY + goodsNameLabelH

+ 10;
}
CGFloat costPriceLabelX = goodsNameLabelX;
CGFloat costPriceLabelW = 180;
CGFloat costPriceLabelH = 30;
_costPriceLabelFrame = CGRectMake(costPriceLabelX, costPriceLabelY, costPriceLabelW, costPriceLabelH);
CGFloat buyButtonW = 80;
CGFloat buyButtonX = goodsNameLabelX + goodsNameLabel

W - buyButtonW;
CGFloat buyButtonY = costPriceLabelY;
CGFloat buyButtonH = costPriceLabelH;
_buyButtonFrame = CGRectMake(buyButtonX, buyButtonY,

buyButtonW, buyButtonH);
_calculateHeight = CGRectGetMaxY(_buyButtonFrame) + 10;
}
return self;
}

µ±ÐèÒª¶¯Ì¬¼ÆËã¸ß¶ÈµÄʱºò, ÎÒÃÇ¿ÉÒÔʹÓÃframehubÕâÖÖģʽ, Ãû×ÖÊÇ×Ô¼ºÈ¡µÄ, Çë±ð¼û¹Ö, ¶ÔÐÔÄÜÓÐÒªÇóµÄͬѧ¿ÉÒÔ½«¸ß¶È¼ÆËãÖµ»º´æÏÂÀ´, ÒÔÃâcpuÖØ¸´´óÁ¿¼ÆËãµ¼ÖÂÊÖ»úµÄºÄµç.

//
// HYAbroadSelectGoodsViewCell.m
// Mall
//
// Created by Öì˫Ȫ on 12/10/2017.
// Copyright ? 2017 _Zhizi_. All rights reserved.
//
#import "HYAbroadSelectGoodsViewCell.h"
#import "HYAbroadSelectGoodsView.h"
#import "HYGoodsDetailViewController.h"
#import "HYCartNewViewController.h"
#import "UIAlertView+SQExtension.h"
#import "NSString+SQExtension.h"
@interface HYAbroadSelectGoodsViewCell ()
@property (nonatomic,strong) HYAbroadSelectGoodsView * selectGoodsView;
@end
@implementation HYAbroadSelectGoodsViewCell
- (void)dealloc {
#if DEBUG
NSLog(@"--------");
NSLog(@"%@ - execute %s",NSStringFromClass([self class]),__func__);
NSLog(@"--------");
#endif
}
+ (instancetype)cellWithTableView:(UITableView *)tableView {
NSString * identifier = NSStringFromClass([HYAbroadSelectGoodsViewCell class]);
HYAbroadSelectGoodsViewCell * cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell) {
cell = [[HYAbroadSelectGoodsViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
return cell;
}
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
[self setupSubviews];
}
return self;
}
- (HYAbroadSelectGoodsView *)selectGoodsView {
if (!_selectGoodsView) {
_selectGoodsView = [HYAbroadSelectGoodsView new];
_selectGoodsView.backgroundColor = [UIColor whiteColor];
_selectGoodsView.layer.cornerRadius = 4;
_selectGoodsView.layer.masksToBounds = YES;
}
return _selectGoodsView;
}
- (void)setupSubviews {
self.contentView.backgroundColor = SQBGC;
[self.contentView addSubview:self.selectGoodsView];
}
- (void)setGood:(AbroadGoods *)good {
_good = good;
__weak typeof(self) _self = self;
[_selectGoodsView.proImageUrlButton sd_setBackgroundImageWithURL:[NSURL URLWithString:good.proImageUrl] forState:0 placeholderImage:[UIImage imageNamed:@"placeholder_200"]];
[_selectGoodsView.proImageUrlButton whenTapped:^{
[[HYCurrentVCmanager shareInstance].getCurrentVC hyPushDetail:_self.good.targetUrl];
}];
[_selectGoodsView.goodsSellerImageView sd_setImageWithURL:[NSURL URLWithString:good.goodsSellerImage]];
_selectGoodsView.goodsNameLabel.text = [NSString stringWithFormat:@" %@", [good.goodsName trim]];
_selectGoodsView.nameGoodEvalutionLabel.text = [good.nameGoodEvalution trim];
_selectGoodsView.costPriceLabel.text = good.ecPrice;
[_selectGoodsView.buyButton whenTapped:^{
if (_self.good.goodsType == GoodsTypePrescriptionAllow ||
_self.good.goodsType == GoodsTypePrescriptionForbid ||
_self.good.goodsType == GoodsTypeGlasses) {
[[HYCurrentVCmanager shareInstance].getCurrentVC HYPushViewController:[HYGoodsDetailViewController new] animated:YES];
} else {
[_self.abroadshoppinghomeOperator senderAddShoppingCartWithModel:nil goodsId:_self.good.goodsId completion:^{
[UIAlertView showAlertViewWithTitle:@"Ìí¼Ó³É¹¦!" message:@"ÉÌÆ·ÒѼÓÈ빺Îï³µ" cancelButtonTitle:@"ÔÙ¹ä¹ä" otherButtonTitles:@[@"È¥¹ºÎï³µ"] clickAtIndex:^(NSInteger buttonIndex) {
if (buttonIndex == 1) {
[[HYCurrentVCmanager shareInstance].getCurrentVC HYPushViewController:[HYCartNewViewController new] animated:YES];
}
}];
}];
}
}];
[_selectGoodsView setNeedsLayout];
[self setNeedsLayout];
}
- (void)layoutSubviews {
[super layoutSubviews];
CGFloat selectGoodsViewX = 15;
CGFloat selectGoodsViewY = 0;
CGFloat selectGoodsViewW = self.width - 2 * selectGoodsViewX;
CGFloat selectGoodsViewH = [HYAbroadSelectGoodsView viewHeightWithGoodsName:[NSString stringWithFormat:@" %@", [_good.goodsName trim]] nameGoodEvalution:[_good.nameGoodEvalution trim]];
_selectGoodsView.frame = CGRectMake(selectGoodsViewX, selectGoodsViewY, selectGoodsViewW, selectGoodsViewH);
}
+ (CGFloat)cellHeightWithGood:(AbroadGoods *)good {
return [HYAbroadSelectGoodsView viewHeightWithGoodsName:[NSString stringWithFormat:@" %@", [good.goodsName trim]] nameGoodEvalution:[good.nameGoodEvalution trim]] + 10;
}

¿ÉÒÔ¿´µ½, ÍÆ¼ö½«tableviewcellµÄ¸ß¶È¼°»ñÈ¡·â×°ÔÚÄÚ, ±ÜÃâºÍtableview½øÐÐñîºÏ, ÕâÀï×¢ÒâµÄÊÇÒÔÏ´úÂë:

[_self.abroadshoppinghomeOperator senderAddShoppingCartWithModel:nil goodsId:_self.good.goodsId completion:^{
[UIAlertView showAlertViewWithTitle:@"Ìí¼Ó³É¹¦!" message:@"ÉÌÆ·ÒѼÓÈ빺Îï³µ" cancelButtonTitle:@"ÔÙ¹ä¹ä" otherButtonTitles:@[@"È¥¹ºÎï³µ"] clickAtIndex:^(NSInteger buttonIndex) {
if (buttonIndex == 1) {
[[HYCurrentVCmanager shareInstance].getCurrentVC HYPushViewController:[HYCartNewViewController new] animated:YES];
}
}];
}];

Ö±½ÓÔÚsubviewÖлñÈ¡ÁËÇëÇóµÄÂß¼­, µ±µ÷ÓÃopeatorµÄ·½·¨Ê±»áͨ¹ýpresenterÖмä¼þ´«µÝ¸øviewmodel½øÐÐÇëÇó, µ±ÇëÇó³É¹¦ºó½øÐи³Öµ²Ù×÷Ë¢ÐÂtableview, ×îºó»Øµ÷×Ô¶¨Òå²Ù×÷µ¯³öÁËalert¿ò, ÓÉÓÚ¶¼ÊÇÖ÷Ï̲߳Ù×÷, Ò²²»»áÓÐḬ̈߳²È«µÄÎÊÌâ.

//
// Router.swift
// RouterPatterm
//
// Created by ˫Ȫ Öì on 17/4/12.
// Copyright ? 2017Äê Doubles_Z. All rights reserved.
//
import UIKit
class Router {
static let shareRouter = Router()
var params: [String : Any]?
var routers: [String : Any]?
fileprivate let map = ["J1" : "Controller"]
func guardRouters(finishedCallback : @escaping () -> ()) {
Http.requestData(.get, URLString: "http://localhost:

3001/api/J1/getRouters") { (response) in
guard let result = response as? [String : Any] else

{ return }
guard let data:[String : Any] = result["data"] as?

[String : Any] else { return }
guard let routers:[String : Any] = data["routers"]

as? [String : Any] else { return }
self.routers = routers
finishedCallback()
}
}
}
extension Router {
func addParam(key: String, value: Any) {
params?[key] = value
}
func clearParams() {
params?.removeAll()
}
func push(_ path: String) {
guardRouters {
guard let state = self.routers?[path] as? String else { return }
if state == "app" {
guard let nativeController = NSClassFromString

("RouterPatterm.\(self.map[path]!)") as? UIView

Controller.Type else { return }
currentController?.navigationController?.pushVi

ewController(nativeController.init(), animated: true)
}
if state == "web" {
let host = "http://localhost:3000/"
var query = ""
let ref = "client=app"
guard let params = self.params else { return }
for (key, value) in params {
query += "\(key)=\(value)&"
}
self.clearParams()
let webViewController = WebViewController("\(host)

\(path)?\(query)\(ref)")
currentController?.navigationController?.pushView

Controller(webViewController, animated: true)
}
}
}
}

ÓÉÓÚÏßÉÏÕæÊµÏîÄ¿µÄ·ÓÉÉæ¼°¹«Ë¾ÒµÎñ, ÕâÀï¾Íͨ¹ýÎÒµÄÒ»¸öСdemo½øÐн²½â, routerµÄ±¾ÖʾÍÊÇÒ»¸öÓ³Éä, Ê×ÏÈrouterÀàÊÇÒ»¸öµ¥Àý, ÐèÒªÓÐÌí¼ÓºÍɾ³ý²ÎÊýµÄ½Ó¿Ú, ÒÔ¼°¿ÉÒÔÇø·ÖÊÇnativeºÍh5µÄÉè¼Æ, ÒÔ¼°Ö®Ç°½²µ½µÄ½µ¼¶, ²»Óÿ´Ò»Ð©Èý·½¿âµÄÉè¼Æ¶àô¿áìÅ, ¾¿Æä±¾ÖÊ»¹ÊǶÔÓÚ"\(host)\(path)?\(query)\(ref)"½øÐÐÂß¼­²ð·Ö, ʹÓ÷Óɵĺô¦Êǵ±Ê¹ÓÃcocoapod˽Óпâ×é¼þ»¯µÄʱºò, ÍêÈ«±ÜÃâÁË¶à¿ØÖÆÆ÷Ö®¼äµÄñîºÏ.

#import <objc/runtime.h>
@interface MySafeDictionary : NSObject
@end
static NSLock *kMySafeLock = nil;
static IMP kMySafeOriginalIMP = NULL;
static IMP kMySafeSwizzledIMP = NULL;
@implementation MySafeDictionary
+ (void)swizzlling {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
kMySafeLock = [[NSLock alloc] init];
});
[kMySafeLock lock];
do {
if (kMySafeOriginalIMP || kMySafeSwizzledIMP) break;
Class originalClass = NSClassFromString(@"__NSDictionaryM");
if (!originalClass) break;
Class swizzledClass = [self class];
SEL originalSelector = @selector(setObject:forKey:);
SEL swizzledSelector = @selector(safe_setObject:forKey:);
Method originalMethod = class_getInstanceMethod(originalClass, originalSelector);
Method swizzledMethod = class_getInstanceMethod(swizzledClass, swizzledSelector);
if (!originalMethod || !swizzledMethod) break;
IMP originalIMP = method_getImplementation(originalMethod);
IMP swizzledIMP = method_getImplementation(swizzledMethod);
const char *originalType = method_getTypeEncoding(originalMethod);
const char *swizzledType = method_getTypeEncoding(swizzledMethod);
kMySafeOriginalIMP = originalIMP;
kMySafeSwizzledIMP = swizzledIMP;
class_replaceMethod(originalClass,swizzledSelector,

originalIMP,originalType);
class_replaceMethod(originalClass,originalSelector,

swizzledIMP,swizzledType);
} while (NO);
[kMySafeLock unlock];
}
+ (void)restore {
[kMySafeLock lock];
do {
if (!kMySafeOriginalIMP || !kMySafeSwizzledIMP) break;
Class originalClass = NSClassFromString(@"__NSDictionaryM");
if (!originalClass) break;
Method originalMethod = NULL;
Method swizzledMethod = NULL;
unsigned int outCount = 0;
Method *methodList = class_copyMethodList(originalClass, &outCount);
for (unsigned int idx=0; idx < outCount; idx++) {
Method aMethod = methodList[idx];
IMP aIMP = method_getImplementation(aMethod);
if (aIMP == kMySafeSwizzledIMP) {
originalMethod = aMethod;
}
else if (aIMP == kMySafeOriginalIMP) {
swizzledMethod = aMethod;
}
}
// ¾¡¿ÉÄÜʹÓÃexchange,ÒòΪËüÊÇatomicµÄ
if (originalMethod && swizzledMethod) {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
else if (originalMethod) {
method_setImplementation(originalMethod, kMySafeOriginalIMP);
}
else if (swizzledMethod) {
method_setImplementation(swizzledMethod, kMySafeSwizzledIMP);
}
kMySafeOriginalIMP = NULL;
kMySafeSwizzledIMP = NULL;
} while (NO);
[kMySafeLock unlock];
}
- (void)safe_setObject:(id)anObject forKey:(id<NSCopying>)aKey {
if (anObject && aKey) {
[self safe_setObject:anObject forKey:aKey];
}
else if (aKey) {
[(NSMutableDictionary *)self removeObjectForKey:aKey];
}
}

¶ÔÓÚAOPÕâÖÖ, ÎÒ½ØÈ¡ÁËһλ´óÀв©¿ÍÖеĴúÂë, ¿ÉÒÔ¿´µ½µÄÊÇ, µ±¶àÏ̵߳Äʱºò, ÎÒÃÇÖ»ÐèÒªÔÚhookµÄʱºò½øÐмÓËøºÍ½âËø±£³ÖḬ̈߳²È«¾Í¿ÉÒÔÁË, µ±È»Ò²¿ÉÒÔʹÓÃAspectsÕâ¸ö¿âÀ´¼ò»¯hook²Ù×÷,±Ï¾¹AOPÕâ¿éÊÇÒª¿´ÒµÎñÂß¼­µÄ, ²¢²»ÄÜÒ»¸Å¶øÂÛ.

//
// UIViewController+hook.m
// SQTemplate
//
// Created by Öì˫Ȫ on 23/11/2017.
// Copyright ? 2017 Doubles_Z. All rights reserved.
//
#import "UIViewController+hook.h"
#import "CurrentViewController.h"
#import <Aspects.h>
@implementation UIViewController (hook)
+ (void)load {
[UIViewController aspect_hookSelector:@selector(viewWillAppear:) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> aspectInfo, BOOL animated) {
kCurrentViewController = aspectInfo.instance;
} error:NULL];
}

×î³£ÓõÄAOP¾ÍÊÇhookÉúÃüÖÜÆÚÀ´»ñÈ¡µ±Ç°¿ØÖÆÆ÷, ͨ¹ýÒ»¸öÈ«¾Ö±äÁ¿¿ÉÒÔÈ«·½Î»»ñÈ¡, ÒÔÉÏ´úÂë¾ÍÊÇͨ¹ýAOPģʽ½øÐÐÃæÏòÇÐÆ¬±à³Ì, ±ÜÃâÐèÒª¼Ì³ÐÒ»¸ö»ùÀà¶ø´øÀ´µÄÇ¿ñîºÏ.

Éú³É¹¤¾ß

Ëùν¹¤ÓûÉÆÆäʱØÏÈÀûÆäÆ÷, ÉÏÃæµÄ¼Ü¹¹Éè¼ÆËäºÃ, µ«ÒªÈÃÆäËûͬѧģ·Âд·¨ÊµÔÚÊÇÌ«Âé·³ÁË, Ò²»áµ¼Öµִ¥ÇéÐ÷, µ«ÎªÁËÎÒÃÇ֮ǰ´úÂë¹æ·¶µÄÄ¿±ê, ¼Ü¹¹Éè¼ÆµÄÖ´ÐÐÒ²ÊÇÖ¾ÔÚ±ØÐÐ, ÕâʱÎÒÃǾÍÐèÒª½øÐдúÂë×Ô¶¯Éú³ÉµÄ¹¤×÷.

ËùνµÄ´úÂëÉú³É¾¿Æä±¾ÖʾÍÊÇ×Ö·û´®Ìæ»», ¾ÍÊǽ«¿É±äµÄ×Ö·û´®Ì滻ģ°åÖеıê¼Ç, ES6ÖеÄÄ£°å×Ö·û´®${±äÁ¿}Ò²ÊÇÕâ¸öµÀÀí.

ÎÒÃÇÀ´¿´Ò»ÏÂÄ£°å:

//
// InterfaceTemplate.h
// SQTemplate
//
// Created by ˫Ȫ Öì on 17/5/5.
// Copyright ? 2017Äê Doubles_Z. All rights reserved.
//
#import <UIKit/UIKit.h>
@protocol <#Root#><#Unit#>ModelInterface <NSObject>
<#ModelInterface#>
@end
@protocol <#Root#><#Unit#>ViewModelInterface <NSObject>
@optional
@property (nonatomic,strong) id<<#Root#><#Unit#>ModelInterface> model;
@optional
- (void)initializeWithModel:(id<<#Root#><#Unit#>ModelInterface>)model <#InitializeInterface#>completion:(void(^)())completion;
<#ViewModelInterface#>
@end
@protocol <#Root#><#Unit#>ViewInterface <NSObject>
@property (nonatomic,weak) id<<#Root#><#Unit#>ViewModelInterface> <#unit#>ViewModel;
@property (nonatomic,weak) id<<#Root#><#Unit#>ViewModelInterface> <#unit#>Operator;

²¢½øÐжÁд²Ù×÷:

//
// SQFileParser.m
// SQBuilder
//
// Created by Öì˫Ȫ on 17/08/2017.
// Copyright ? 2017 Castie!. All rights reserved.
//
#import "SQFileParser.h"
@implementation SQFileParser
+ (NSDictionary *)parser_plist_r {
NSBundle * bundle = [NSBundle bundleWithPath:

[[NSBundle mainBundle] pathForResource:@"builder.

bundle" ofType:nil]];
NSDictionary * config = [NSDictionary dictionaryWithContentsOfFile:[bundle pathForResource:@"config/config.plist" ofType:nil]];
NSMutableDictionary * plist = [NSDictionary dictionaryWithContentsOfFile:[bundle pathForResource:

[NSString stringWithFormat:@"config/%@.plist",config[@"builder

Source"]] ofType:nil]].mutableCopy;
[config enumerateKeysAndObjectsUsingBlock:^(id

_Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
[plist setObject:obj forKey:key];
}];
return plist;
}
+ (void)parser_rw:(NSString *)path code:(NSString *)

code filename:(NSString *)filename header:(NSString *)

header parameter:(NSMutableArray *)parameter {
NSString * arch = [[filename componentsSeparatedByString:@"."]firstObject];
NSString * suffix = [[filename componentsSeparatedByString:@"."]lastObject];
NSString * filename_r = [NSString stringWithFormat:@"%@Template.%@", arch,suffix];
NSString * filename_w = [NSString stringWithFormat:

@"%@/%@%@.%@", path,header,arch,suffix];
NSString * template = [SQFileParser parser_r:

filename_r code:[code lowercaseString]];
[[SQFileParser replaceThougth:template parameter

:parameter] writeToFile:filename_w atomically:YES encoding:NSUTF8StringEncoding error:nil];
}
+ (NSString *)parser_r:(NSString *)filename code:

(NSString *)code {
NSBundle * bundle = [NSBundle bundleWithPath

:[[NSBundle mainBundle] pathForResource:@"builder.

bundle" ofType:nil]];
return [NSMutableString stringWithContentsOfFile:

[bundle pathForResource:[NSString stringWithFormat:@"template/%@/%@", code, filename]

ofType:nil] encoding:NSUTF8StringEncoding error:nil];
}
static NSString * code;
+ (NSString *)replaceThougth:(NSString *)templete parameter:(NSMutableArray *)parameter {
__block NSString * temp = templete;
[[parameter firstObject] enumerateKeysAndObjectsUsingBlock:^(NSString *

_Nonnull key, NSString * _Nonnull obj, BOOL *

_Nonnull stop) {
temp = [templete stringByReplacingOccurrencesO

fString:key withString:obj];
}];
[parameter removeObjectAtIndex:0];
if (parameter.count) {
[SQFileParser replaceThougth:temp parameter:

parameter];
} else {
code = temp;
}
return code;
}

¹ØÓÚÉú³É¹¤¾ßµÄ¿ª·¢Ö®Ç°ÓÐһƪÏêϸÂÛÊöÁË, ÕâÀï¾Í²»¹ý¶à׸ÊöÁË. µã»÷Ìø×ª

ÎÒ˾ÒѾ­Í¨¹ý¶ÁÈ¡±í¸ñ½øÐÐÉú³ÉiOSºÍAndroidÁ½¶ËµÄ´úÂë, ±£³ÖÁ½¶ËÂß¼­Ïàͬ, µ«ÓÉÓÚ±í¸ñµÄÉè¼ÆÓ빫˾ҵÎñ¼°¸öÈËϰ¹ßÏà¹Ø, Õⲿ·Ö´úÂë²»Ó蹫¿ª, ÇëÁ½â.

¿ÉÒÔ¿´µ½Éú³ÉµÄÎļþͨ¹ýÎļþ¼ÐµÄÐÎʽ´æÔÚ, Ö»ÐèÒª½«Îļþ¼Ðµ¼ÈëÏîÄ¿Öм´¿ÉÁ¢¼´»ñµÃ֮ǰËùÉè¼ÆµÄ¼Ü¹¹.

×îºóÎÒ½«¼Ü¹¹demoÒÔ¼°¹¤¾ß·ÅÔÚÁËgithubÉÏ, ¹ØÓÚÉÏÃærouter½µ¼¶Õâ¿é¿ÉÒÔµã»÷ÕâÀïÏÂÔØ

ÈçºÎʹÓÃ

git clone | download ºó´ò¿ªSQTemplate¹¤×÷¿Õ¼ä, ¾ÍÄܹ»¿´µ½Á½¸öÏîÄ¿.

SQBuilderÊÇÉú³É¹¤¾ßµÄÏîÄ¿.

ÅäÖÃÉú³É¹¤¾ßµÄ½Ó¿ÚÎĵµ×ֶκó, µã»÷Run¼´¿ÉÉú³É´úÂë, ÏÔʾÔÚ×ÀÃæ.

SQTemplateÊÇÄ£°åÉú³ÉºóÔÚÏîÄ¿ÖÐʹÓõÄdemo.

¿ÉÒÔ¿´µ½ÉÏÊöËùÓеļܹ¹Éè¼ÆÄ£Ê½µÄ¼òµ¥ÒýÓÃ, µã»÷ÃëËÙÎåÀåÃ×µÄͼƬ, ¿ÉÒÔͨ¹ý·ÓÉÌø×ªµ½ÏÂÒ»Ò³Ãæ.

ͼƬÏÂÃæµÄÊý¾ÝÊÇͨ¹ýkoa·þÎñ·µ»ØµÄÊý¾Ý, ÏÂÔØcoderZsq.target.swiftÖеÄRouterPatternÖеÄ/server/RouterPattern, cd½øÈ¥ºóÖ´ÐÐnpm start, ¼´¿É¿ªÆô·þÎñ. µ±È»ÄãÐèÒªNode, »·¾³ºÍwebpackµÄÈ«¾Ö»·¾³.

Èç¹ûÄãÐèÒª²é¿´Á˽âRouter²¿·Ö, ¿ÉÒÔͨ¹ýcoderZsq.target.swiftÕâ¸öÏîÄ¿½øÐÐѧϰ½»Á÷.

1.app/RouterPattern Ö±½ÓË«»÷´ò¿ªÏîÄ¿¼´¿É

2.web/RouterPattern cd ½øÈ¥ npm run dev

3.server/RouterPattern cd ½øÈ¥ npm start

 

   
2414 ´Îä¯ÀÀ       28
Ïà¹ØÎÄÕÂ

Éî¶È½âÎö£ºÇåÀíÀôúÂë
ÈçºÎ±àд³öÓµ±§±ä»¯µÄ´úÂë
ÖØ¹¹-ʹ´úÂë¸ü¼ò½àÓÅÃÀ
ÍŶÓÏîÄ¿¿ª·¢"±àÂë¹æ·¶"ϵÁÐÎÄÕÂ
Ïà¹ØÎĵµ

ÖØ¹¹-¸ÄÉÆ¼ÈÓдúÂëµÄÉè¼Æ
Èí¼þÖØ¹¹v2
´úÂëÕû½àÖ®µÀ
¸ßÖÊÁ¿±à³Ì¹æ·¶
Ïà¹Ø¿Î³Ì

»ùÓÚHTML5¿Í»§¶Ë¡¢Web¶ËµÄÓ¦Óÿª·¢
HTML 5+CSS ¿ª·¢
ǶÈëʽC¸ßÖÊÁ¿±à³Ì
C++¸ß¼¶±à³Ì