±à¼ÍƼö: |
±¾ÎÄÀ´×ÔÓÚ²©¿Í¾ò½ð£¬ÕâÆªÎÄÕÂÖ÷ÒªÏêϸÐðÊöÁËÕâ¸ö¼Ü¹¹¹¤¾ßµÄÉè¼ÆË¼Â·ÒÔ¼°Ò»²½²½µÄÓÅ»¯,
ÈçºÎ¿ª·¢³öÊʺÏ×Ô¼ºµÄͨÓüܹ¹Éè¼Æ. |
|
Éè¼ÆË¼Â·

¶ÔÓڼܹ¹, ÒÆ¶¯¶Ë³£¼ûµÄ¼Ü¹¹Éè¼Æ°üÀ¨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
|