ãååã«åæãããéæ³ã¯ãæè¡ãšèŠåããã€ããŸãããã
ã¢ãŒãµãŒã»ã¯ã©ãŒã¯
ïŒTyphoon Frameworkãããžã§ã¯ãã®å ¬åŒwikiã®ãšãã°ã©ãïŒ
ãµã€ã¯ã«ãiOSã¢ããªã±ãŒã·ã§ã³ã®äŸåé¢ä¿ãæ£ãã管çããã
- å°é¢šã®çŽ¹ä»
- å°é¢šè£ 眮
- ã¢ãžã¥ã©ãªãã£å°é¢š
- å°é¢šã®ãã³ããšã³ã
- å°é¢šã®ä»£æ¿
- ïŒãªãã·ã§ã³ïŒRambler.iOSïŒ3ã iOSã§ã®äŸåæ§æ³šå ¥ã ã¹ã©ã€ã
- ïŒãªãã·ã§ã³ïŒRambler.iOSïŒ3ã iOSã§ã®äŸåæ§æ³šå ¥ã æ å
ã¯ããã«
ãã®ã·ãªãŒãºã®èšäºã®äžéšãšããŠãç§ã¯çè«ãæãäžããã äŸåæ§å転ã®åçãŸãã¯äŸåæ§æ³šå ¥ã®ãã¿ãŒã³ãæ€èšããŸã-èªè ã¯ãã§ã«ZenãåŠç¿ããæºåãã§ããŠããããšãåœç¶ãšèŠãªããå®è·µã«çŽè¡ããŸãïŒçè«ã«æ £ããããã®ãªã³ã¯ã¯ãã¹ãã®æåŸïŒã
Typhoon Frameworkã¯ãObjective-Cããã³Swiftã¢ããªã±ãŒã·ã§ã³åãã®DIã³ã³ããã®æãæåã§äººæ°ã®ããå®è£ ã§ãã ãããžã§ã¯ãã¯éåžžã«è¥ãã§ã-æåã®ã³ãããã¯2012幎ã®çµããã«è¡ãããŸãããããã§ã«å€ãã®ãã¡ã³ãç²åŸããŠããŸãã äœæè ã«ãããããžã§ã¯ãã®ç©æ¥µçãªãµããŒãïŒãã®ãã¡1ã€ã¯ãªã ã¹ã¯ã«äœãã§ããŸãïŒã¯ç¹çã«å€ããŸã-äœæãããåé¡ã®å€§éšåã¯10å以å ã«åçãããæ°æéåŸã«ããŒã å šäœããã£ã¹ã«ãã·ã§ã³ã«åå ããŸãã
å°é¢šãå¿ èŠãªã®ã¯ãªãã§ããïŒ ç¥èªã§çããŸã-IoCã ç§ã¯ãã§ã«çè«ã«å ¥ããªãããšãçŽæããŠããã®ã§ã Martin Fowlerã«èšåããã ãã§ãã
Typhoonã®äž»ãªæ©èœãããã€ãèŠãŠã¿ãŸããããããã¯ãiOSéçºè ã®æ³šç®ãéããã®ã«ååãªã¯ãã§ãã
- 絶察çãã€å®å šã«ãã€ãã£ãã XMLããã¯ããããžãã¯ã©ã€ã³ã¯ãããŸãããXcodeãæäŸãããããã®å°æ°ã®å©ç¹ã¯ãã¹ãŠãã³ã³ãã€ã«æ®µéã§ã®ãªãã¡ã¯ã¿ãªã³ã°ãèªåè£å®ãã³ãŒãæ€èšŒãå®å šã«ãµããŒãããŠããŸãã
- ã¢ãžã¥ãŒã«æ§ã¯éåžžã«å®è£ ãããŠããŸã-åçŽå±€ãšæ°Žå¹³å±€ã®äž¡æ¹ã«åå²ãããä»»æã®æ°ã®å·¥å Žã§äœæ¥ã§ããŸãã
- Storyboardsãšå®å šã«çµ±åãããŠãããããäŸåé¢ä¿ãViewControllersã«çŽæ¥åã蟌ãããšãã§ããŸãã
- ãã¹ãŠã®äŸåæ§æ³šå ¥ãã¿ãŒã³ããµããŒãããŸã ïŒã€ãã·ã£ã©ã€ã¶ãŒæ³šå ¥ãããããã£æ³šå ¥ãã¡ãœããæ³šå ¥ïŒããã³åŸè ã®ããã«ãç¹å¥ãªããã¯ãæäŸãããŸãïŒã
- 埪ç°äŸåé¢ä¿ã®æ³šå ¥ããµããŒã-äŸãšããŠãViewControllerã¯ãªããžã§ã¯ããä¿æãããã®ããªã²ãŒãã§ãã
- 倧ããªãã€ããªãæã€ãã¡ã€ã¿ãŒã¯å¹³åã«ç ãããšãã§ããŸã-ãã¬ãŒã ã¯ãŒã¯ã®ãã¹ãŠã®ã¢ãžã¥ãŒã«ãå æããã³ãŒãã¯ããã3,000è¡ã§ã
ïŒ2ã€ã®éåžžã®ViewControllerã®ããã«ïŒ
åºæ¬çãªãããžã§ã¯ãçµ±å
Typhoonãã¯ãªãŒã³ãªã¢ããªã±ãŒã·ã§ã³ã«ç°¡åã«çµ±åã§ããããšã瀺ãããã«ãé©åãªæ¹æ³ã§ã¢ããªã±ãŒã·ã§ã³ãæ§æã§ããAppDelegateã§startUpConfiguratorãªããžã§ã¯ããå®è£ ããå ŽåãèããŸãã
@interface RIAppDelegate @property (strong, nonatomic) id <RIStartUpConfigurator> startUpConfigurator; @end
- ç¬èªã®ãµãã¯ã©ã¹TyphoonAssembly ïŒDIã³ã³ãããŒïŒãäœæããŸãã
@interface RIAssembly : TyphoonAssembly - (RIAppDelegate *)appDelegate; @end
å®éããã®ã¡ãœããã¯ã€ã³ã¿ãŒãã§ã€ã¹ã§å®£èšãããŠããªãå ŽåããããŸãããæè²ç®çã®ããã«ããã«æ®ããŠãããŸãã
- RIAssemblyã®å®è£
ãå®è£
ããŸãã
@implementation RIAssembly - (RIAppDelegate *)appDelegate { return [TyphoonDefinition withClass:[RIAppDelegate class] configuration:^(TyphoonDefinition *definition) { [definition injectProperty:@selector(startUpConfigurator) with:[self startUpConfigurator]]; } } - (id <RIStartUpConfigurator>)startUpConfigurator { return [TyphoonDefinition withClass:[RIStartUpConfiguratorBase class]]; } @end
ã³ã³ãã£ã°ã¬ãŒã¿ã«TyphoonDefinitionãè¿ãã¡ãœããã§ã¯ãè¿œå ã®æ³šå ¥ã¯å®è¡ãããŸããããä»åŸãããçºçããã®ãé²ããã®ã¯äœããªãããšã«æ³šæããŠãã ããã ããšãã°ãã¢ããªã±ãŒã·ã§ã³ã®keyWindowãæž¡ããŠã rootViewControllerãèšå®ã§ããŸãã
- å®çŸ©äžãDIã³ã³ãããŒã¯å¯èœãªéãèªååããå¿
èŠããããŸã ãTyphoonAssemblyããäœããæåã§èŠæ±ããããšã¯æãŸãããããŸããã æè¯ã®ãªãã·ã§ã³ã¯ã Info.plistãã¡ã€ã«ã䜿çšããããšã§ãã ç§ãã¡ã«å¿
èŠãªã®ã¯ãç¹å®ã®ããŒã®äžã«ãã¢ããªã±ãŒã·ã§ã³ã®èµ·åæã«ã¢ã¯ãã£ãåããå¿
èŠããããã¡ã¯ããªã®ã¯ã©ã¹ã®ååãè¿œå ããããšã§ãã
ããã§èšå®å šäœãå®äºããŸãã æåŸã«äœãåŸããããèŠãŠã¿ãŸãããã
- -applicationDidFinishLaunchingã¡ãœããã«ãã¬ãŒã¯ãã€ã³ããèšå®ããã¢ããªã±ãŒã·ã§ã³ãå®è¡ããŸãã
ã³ã³ãã£ã®ã¥ã¬ãŒã¿ãŒã¯ãå¿ èŠãªã¯ã©ã¹ãæ£åžžã«æ¿å ¥ããŸããïŒ RIAppDelegateèªäœã¯ãå®çŸ©ãããããã³ã«ã«åŸã£ãŠåäœããããšãæãåºããŠãã ããïŒã
ã芧ã®ãšãããTyphoonã®åºæ¬çãªçµ±åã«ã¯æ°åããããããŸããã ããã«ããã¬ãŒã ã¯ãŒã¯ãé·ãèšè¿°ã®ã¢ããªã±ãŒã·ã§ã³ã«åã蟌ãããšãã§ããŸããããã®å Žåãåã³ã®çšåºŠã¯ã³ãŒãèšèšã®å質ã«äŸåããŸãã
ããããã»ããã¢ããæé ã«èå³ããã人ã¯-Ramblerãããžã§ã¯ãã§Typhoonã䜿çšããå®éã®ã±ãŒã¹ãèŠãŠã¿ãŸãããã
RamblerãMailã§ã®Typhoonã®äœ¿çšäŸ
- ç¹å®ã®ãããã³ã«ãå®è£
ããåçŽãªã€ã³ã¹ã¿ã³ã¹ãäœæããã«ã¯ãäœæãããªããžã§ã¯ãã®ã¯ã©ã¹ãæå®ããã ãã§ãã
- (id <RCMStoryboardBuilder>)storyboardBuilder { return [TyphoonDefinition withClass:[RCMStoryboardBuilderBase class]]; }
- RCMAuthorizationPopoverBuilderBaseã«ã¯storyboardBuilderãªããžã§ã¯ããå¿
èŠã§ãããã®ãªããžã§ã¯ãã¯äœææ¹æ³ãæ¢ã«åŠç¿ããŠããŸãã äŸåé¢ä¿ã°ã©ãã«æ¿å
¥ããã«ã¯ãé©åãªã¡ãœãã[self storyboardBuilder]ãåŒã³åºãã ãã§ãã ãããã£ãŠãã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ãäœæããã ãã§ãªãããã®ãã¹ãŠã®äŸåé¢ä¿ãã€ã³ã¹ããŒã«ããŸããã
- (id <RCMPopoverBuilder>)authorizationPopoverBuilder { return [TyphoonDefinition withClass:[RCMAuthorizationPopoverBuilderBase class] configuration:^(TyphoonDefinition *definition) { [definition injectProperty:@selector(storyboardBuilder) with:[self storyboardBuilder]]; }]; }
- RCMNetworkLoggerBaseã¯ã©ã¹ã®ãªããžã§ã¯ããã·ã³ã°ã«ãã³ã«ããã-ãªããžã§ã¯ãã®ã©ã€ããµã€ã¯ã«ã®èšå®ãæ
åœããTyphoonDefinitionã® scopeããããã£ãããã«åœ¹ç«ã¡ãŸãã
- (id <RCMLogger>)networkLogger { return [TyphoonDefinition withClass:[RCMNetworkLoggerBase class] configuration:^(TyphoonDefinition *definition) { definition.scope = TyphoonScopeSingleton; }]; }
- TyphoonãInitializer Injectionãå®è£
ããæ¹æ³ãèŠãŠã¿ãŸãããã åäœããã«ã¯ãèšå®ãµãŒãã¹ã«ã¯2ã€ã®å¿
é ã®äŸåé¢ä¿ãå¿
èŠã§ãããããã¯ãŒã¯èŠæ±ãåŠçã§ããnetworkClientãš ãããŸããŸãªãŠãŒã¶ãŒè³æ Œæ
å ±ãæ ŒçŽããcredentialsStorageã§ãã TyphoonDefinitionã®-useInitializerã¡ãœããã¯ãç¹å®ã®åæåã»ã¬ã¯ã¿ãŒãšããã©ã¡ãŒã¿ãŒãåæååã«åã蟌ãŸããŠãããããã¯ãåãå
¥ããŸãã
- (id <RCMSettingsService>)settingsService { return [TyphoonDefinition withClass:[RCMSettingsServiceBase class] configuration:^(TyphoonDefinition *definition) { [definition useInitializer:@selector(initWithClient:sessionStorage:) parameters:^(TyphoonMethod *initializer) { [initializer injectParameterWith:[self mailXMLRPCClient]]; [initializer injectParameterWith:[self credentialsStorage]]; }]; }]; }
- 次ã«ãã¡ãœããã€ã³ãžã§ã¯ã·ã§ã³ã®å®è£
ã調ã¹ãŠã¿ãŸãããã ãšã©ãŒãµãŒãã¹ã¯ãåä¿¡ããNSErrorããã¹ãŠã®çœ²åæžã¿ãã³ãã©ãŒã«éä¿¡ã§ããŸãã æªåŠçã®ãšã©ãŒããã¹ãŠãã°ã«èšé²ãããããã«ããã«ã¯ããµãŒãã¹ãäœæããçŽåŸã«æšæºãã³ãã©ãŒã«çœ²åããŸãã
- (id <RCMErrorService>)errorService { return [TyphoonDefinition withClass:[RCMErrorServiceBase class] configuration:^(TyphoonDefinition *definition) { [definition injectMethod:@selector(addErrorHandler:) parameters:^(TyphoonMethod *method) { [method injectParameterWith:[self defaultErrorHandler]]; }]; }]; }
- ã¢ããªã±ãŒã·ã§ã³ã®ãã¹ãŠã®ViewControllersã«ã¯ã3ã€ã®äŸåé¢ä¿ãå¿
èŠã§ãããšã©ãŒåŠçãµãŒãã¹ãåä¿¡ãããã¹ãŠã®NSErrorãªããžã§ã¯ããééãããããã€ãã®äžè¬çãªãšã©ãŒã³ãŒããé©åã«åŠçã§ããåºæ¬ãšã©ãŒãã³ãã©ãããã³åºæ¬ã«ãŒã¿ãŒã§ãã ãã¹ãŠã®ã³ã³ãããŒã©ãŒã§ãã®ã³ãŒãã®éè€ãé¿ããããã«ãããã3ã€ã®äŸåé¢ä¿ãããŒã¹ã®TyphoonDefinitionã«æ³šå
¥ããŸãã ã ä»ã®ã¡ãœããã§äœ¿çšããã«ã¯ãåã«èŠªããããã£ãèšå®ããŸãã
- (UIViewController *)baseViewController { return [TyphoonDefinition withClass:[UIViewController class] configuration:^(TyphoonDefinition *definition) { [definition injectProperty:@selector(errorService) with:[self.serviceComponents errorService]]; [definition injectProperty:@selector(errorHandler) with:[self baseControllerErrorHandler]]; [definition injectProperty:@selector(router) with:[self baseRouter]]; }]; } - (UIViewController *)userNameTableViewController { return [TyphoonDefinition withClass:[RCMMessageCompositionViewController class] configuration:^(TyphoonDefinition *definition) { definition.parent = [self baseViewController]; [definition injectProperty:@selector(router) with:[self settingsRouter]]; }]; }
Typhoonã䜿çšãããšãTyphoonDefinitionsã®ç¶æ¿ã®ã¯ããã«è€éãªãã§ãŒã³ãæ§ç¯ã§ããããšã«æ³šæããŠãã ããã
- APIã®URLãããŒãã³ãŒãã£ã³ã°ãã代ããã«ãæ§æplistãã¡ã€ã«ã«ä¿åããŸãã ãã®ç¶æ³ã§ãTyphoonã¯ä»¥äžãæ¯æŽããŸã-å¿
èŠãªãã¡ã€ã«ãã¢ããããŒããããã®ãã£ãŒã«ãããã€ãã£ããªããžã§ã¯ãïŒãã®å Žåã¯NSURL ïŒã«å€æãã èšå®ãã£ãŒã«ãã«ã¢ã¯ã»ã¹ããããã®äŸ¿å©ãªæ§æTyphoonConfigïŒKEYïŒãæäŸããŸãã
- (id)configurer { return [TyphoonDefinition configDefinitionWithName:RCMConfigFileName]; } - (id<RCMRPCClient>)idXMLRPCClient{ return [TyphoonDefinition withClass:[RCMRPCClientBase class] configuration:^(TyphoonDefinition *definition) { [definition useInitializer:@selector(initWithBaseURL:) parameters:^(TyphoonMethod *initializer) { [initializer injectParameterWith:TyphoonConfig(RCMAuthorizationURLKey)]; }]; }]; }
ç¥è©±
Typhoon Frameworkã«è¡šé¢çã«ã®ã¿èå³ãæã£ãŠãã人ã®äžã«ã¯ãäºå®äžåºç€ããªãããã€ãã®ç¥è©±ããããŸãã
- é«ããšã³ããªãŒãããå€
å®éããœãŒã¹ã³ãŒããããã¥ã¡ã³ãããµã³ãã«ãããžã§ã¯ãïŒã¡ãªã¿ã«æ¢ã«3ã€ãããŸãïŒãæãäžãããšãTyphoonã®åºæ¬ååãç解ãããããžã§ã¯ãã§äœ¿çšãéå§ã§ããŸãã æ·±ãæãäžããããªãå Žåã¯ãäŸã䜿ããã«ããã¬ãŒã ã¯ãŒã¯ãã³ãŒãã«é æ»ãªãçµ±åã§ããŸãã
- ãããã°ãžã®åŒ·ã圱é¿
å®éãç§ãã¡ã®ã³ãŒããšTyphoonã®éã«ã¯å®éã®é£çµ¡å ã¯ããã»ã©å€ããããŸããããããã®åå²ç¹ã§ã¯ãéçºè ã¯æ¢ã«æçãªäŸå€ãæã£ãŠããŸãã
- TyphoonããµããŒããåæ¢ããå Žåããããžã§ã¯ãããé€å€ããªã
å°é¢šã¯ãç§ãã¡ãå®éã«ã©ãã§ãçŽæ¥å¯Ÿè©±ããªããããè¯ãã§ã-ãããã£ãŠããããæåŠããããšã¯å°é£ã§ãããããã§ãå¯èœã§ã-èªåã®ã¬ãã«ã®å·¥å Žãšãããã³ãŒããšçµ±åããããã®ã¡ã«ããºã ãæåã§äœæããŠãã ããã
- ããã...ã¹ãŠã£ãºã«ããããŸãïŒ
Objective-Cã¯ãã®ã©ã³ã¿ã€ã ã§æåã§ããããã®ãããªãã¬ãŒã ã¯ãŒã¯ã§ãã®æ©èœã䜿çšããªãããšã¯å°ãªããšãæãã§ãã ããã«ããã®ã³ã³ããŒãã³ããããã©ãã¯ããã¯ã¹ããšããŠäœ¿çšããŸããããã¯ãåã1200ã®ã¹ã¿ãŒããã¹ãŠã®ã¬ãŒãããã§ã«èžãã§ãããšããäºå®ã«äŸåããŠããŸãã
- èªè»¢è»ãæžãããšãã§ããã®ã«ãªãTyphoonãå¿
èŠãªã®ã§ããïŒ
Typhoon Frameworkã¯ãç»é¢éã移åãããšãã«ãªããžã§ã¯ãã®ã°ã©ããäœæããäŸåé¢ä¿ãæž¡ãã³ãŒãã®éãšè€éããå€§å¹ ã«åæžããŸãã ããã«ãã»ã«ããµãŒãã¹ã®ãµãŒãã¹ãã±ãŒã¿ãŒã®äžå©ãªç¹ãªããéäžç®¡çãããäŸåé¢ä¿ç®¡çãæäŸããŸãã èªè ã¯èª°ã§ãç°¡åãªãã¡ã¯ããªãŒãäœæã§ãããšæããŸããããããžã§ã¯ããçºå±ããã«ã€ããŠããã®ã¢ãããŒãã®å¶éã«çŽé¢ãç¶ããããšã«ãªããŸã-ãããŠãé·ãéèãåºããŠãããã°ãããã®ãå®è£ ãããããããžã§ã¯ãã®æ©èœãšããã©ãŒãã³ã¹ãç ç²ã«ããå¿ èŠããããŸãã
ãããã«
åœåãç§ã¯Rambler.iOSã§ã®ã¹ããŒããå®å šã«ç¿»èš³ããŠå°å·ããã€ããã§ãããã2ã3ã®ã»ã¯ã·ã§ã³ãæžããåŸã1ã€ã®èšäºã«ã¯è³æãå€ãããããšã«æ°ä»ããŸããã ãããã£ãŠã次ã®ã·ãªãŒãºã§ã¯ïŒ
ãµã€ã¯ã«ãiOSã¢ããªã±ãŒã·ã§ã³ã®äŸåé¢ä¿ãæ£ãã管çããã
- å°é¢šã®çŽ¹ä»
- å°é¢šè£ 眮
- ã¢ãžã¥ã©ãªãã£å°é¢š
- å°é¢šã®ãã³ããšã³ã
- å°é¢šã®ä»£æ¿
- ïŒãªãã·ã§ã³ïŒRambler.iOSïŒ3ã iOSã§ã®äŸåæ§æ³šå ¥ã ã¹ã©ã€ã
- ïŒãªãã·ã§ã³ïŒRambler.iOSïŒ3ã iOSã§ã®äŸåæ§æ³šå ¥ã æ å