Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

iOSレガシーコード改善ガイド〜マンガボックス開発における事例〜

16,284 views

Published on

2016/01/29に開催されたDeNA TechCon 2016での講演資料です。
https://techcon.dena.com

Objective-CからSwiftへ移行する際のパターンについて話しました。#denatechcon

Published in: Technology
  • Be the first to comment

iOSレガシーコード改善ガイド〜マンガボックス開発における事例〜

  1. 1. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. iOS レガシーコード改善ガイド 1 Jan 29, 2016 松前健太郎 IPプラットフォーム事業部第1部
 DeNA Co., Ltd. ∼マンガボックス開発における事例∼
  2. 2. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 自己紹介 松前健太郎 (id:kenmaz) 2003.4 日立ソリューションズ (旧・日立ソフトウェアエンジニアリング) SIer, Java, Ruby, 他 2009.6 ドワンゴ ニコニコ、他 2013.4 DeNA マンガボックス リードエンジニア 2
  3. 3. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 3
  4. 4. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 4 プロ作家の   描きおろし作品が   毎日更新、無料で読める   マンガ雑誌アプリ
  5. 5. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 5
  6. 6. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 6 電子書籍ストアマンガ投稿
  7. 7. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 本題 7
  8. 8. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. レガシーコードについて 8
  9. 9. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. マンガボックスにおけるレガシーコード •開発スタートから約3年 •iOS6時代のコード多数 •機能追加に伴うコードの複雑化 •レガシーコード化の兆候 9
  10. 10. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. マンガボックスにおけるレガシーコード •開発スタートから約3年 •iOS6時代のコード多数 •機能追加に伴うコードの複雑化 •レガシーコード化の兆候 9 iOSレガシーコード改善ガイド レガシーコード化させないための取り組み
  11. 11. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ①リリースサイクルの見直し ②Swiftへの移行 ③AutoLayoutへの対応 ④設計 ⑤運用・ログ 10 iOS レガシーコード改善ガイド
  12. 12. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ①リリースサイクルの見直し ②Swiftへの移行 ③AutoLayoutへの対応 ④設計 ⑤運用・ログ 10 iOS レガシーコード改善ガイド 後日webで公開できれば・・・
  13. 13. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. Swiftへの移行 11 iOSレガシーコード改善ガイド  その②
  14. 14. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 12 h)ps://developer.apple.com/swi7/ Swift移行の意義
  15. 15. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 12 h)ps://developer.apple.com/swi7/ Swift移行の意義
  16. 16. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 12 h)ps://developer.apple.com/swi7/ • Type  Safe   • Op<onal   • Immutable   • Generics Swift移行の意義
  17. 17. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 12 h)ps://developer.apple.com/swi7/ • Type  Safe   • Op<onal   • Immutable   • Generics Swift移行の意義 言語の安全性=アプリの品質に直結
  18. 18. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. iOSエンジニア 1.5人 どうする 13
  19. 19. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. Swift移行への基本戦略 14
  20. 20. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. Swift移行への基本戦略 1. 既存コードの挙動を破壊しないこと 14
  21. 21. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. Swift移行への基本戦略 1. 既存コードの挙動を破壊しないこと 2. 既存objcコードの修正は極力Swiftで行うこと 14
  22. 22. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. Swift移行への基本戦略 1. 既存コードの挙動を破壊しないこと 2. 既存objcコードの修正は極力Swiftで行うこと 3. 段階的に徐々に移行すすめること 14
  23. 23. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. Swift移行への基本戦略 1. 既存コードの挙動を破壊しないこと 2. 既存objcコードの修正は極力Swiftで行うこと 3. 段階的に徐々に移行すすめること 4. Swiftらしいコードを書いて確実に品質を高めること 14
  24. 24. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. Swift移行への基本戦略 1. 既存コードの挙動を破壊しないこと 2. 既存objcコードの修正は極力Swiftで行うこと 3. 段階的に徐々に移行すすめること 4. Swiftらしいコードを書いて確実に品質を高めること 5. 局所的な妥協は許容 14
  25. 25. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. Swift移行への基本戦略 1. 既存コードの挙動を破壊しないこと 2. 既存objcコードの修正は極力Swiftで行うこと 3. 段階的に徐々に移行すすめること 4. Swiftらしいコードを書いて確実に品質を高めること 5. 局所的な妥協は許容 14 →Mix-and-Match
  26. 26. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. Mix and Match ひとつのプロジェクトでObjective-CとSwiftを混合して使うための機能 15 h)ps://developer.apple.com/library/ios/documenta<on/Swi7/Conceptual/BuildingCocoaApps/MixandMatch.html
  27. 27. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. Mix and Matchを使ったSwift移行パターン 16
  28. 28. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. Mix and Matchを使ったSwift移行パターン 16 ① 延命パターン ② ご新規パターン ③ 切り出しパターン ④ ブリッジパターン ⑤ extensionパターン ⑥ 暴露パターン ⑦ 乗っ取りパターン ⑧ 写経パターン
  29. 29. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. Mix and Matchを使ったSwift移行パターン 16 ① 延命パターン ② ご新規パターン ③ 切り出しパターン ④ ブリッジパターン ⑤ extensionパターン ⑥ 暴露パターン ⑦ 乗っ取りパターン ⑧ 写経パターン パターン  ≒  武道における形
  30. 30. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. Mix and Matchを使ったSwift移行パターン 16 ① 延命パターン ② ご新規パターン ③ 切り出しパターン ④ ブリッジパターン ⑤ extensionパターン ⑥ 暴露パターン ⑦ 乗っ取りパターン ⑧ 写経パターン パターン  ≒  武道における形
  31. 31. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. Mix and Matchを使ったSwift移行パターン 16 ① 延命パターン ② ご新規パターン ③ 切り出しパターン ④ ブリッジパターン ⑤ extensionパターン ⑥ 暴露パターン ⑦ 乗っ取りパターン ⑧ 写経パターン パターン  ≒  武道における形 パターン化する意義
  32. 32. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. Mix and Matchを使ったSwift移行パターン 16 ① 延命パターン ② ご新規パターン ③ 切り出しパターン ④ ブリッジパターン ⑤ extensionパターン ⑥ 暴露パターン ⑦ 乗っ取りパターン ⑧ 写経パターン パターン  ≒  武道における形 パターン化する意義 →  迷わず判断できる
  33. 33. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. Mix and Matchを使ったSwift移行パターン 16 ① 延命パターン ② ご新規パターン ③ 切り出しパターン ④ ブリッジパターン ⑤ extensionパターン ⑥ 暴露パターン ⑦ 乗っ取りパターン ⑧ 写経パターン パターン  ≒  武道における形 パターン化する意義 →  迷わず判断できる
  34. 34. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. Mix and Matchを使ったSwift移行パターン 16 ① 延命パターン ② ご新規パターン ③ 切り出しパターン ④ ブリッジパターン ⑤ extensionパターン ⑥ 暴露パターン ⑦ 乗っ取りパターン ⑧ 写経パターン パターン  ≒  武道における形 パターン化する意義 →  迷わず判断できる ※各パターン名は私による勝手な命名
  35. 35. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ①延命パターン 17 Objec<ve-­‐C swi7
  36. 36. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ①延命パターン 17 objc   class objc   class objc   class Objec<ve-­‐C swi7
  37. 37. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ①延命パターン 17 objc   class objc   class objc   class Nullability,  Genericsに関するアノテーションを付加 Objec<ve-­‐C swi7
  38. 38. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ①延命パターン 17 objc   class objc   class objc   class Nullability,  Genericsに関するアノテーションを付加 型安全・nil  安全  な世界 Objec<ve-­‐C swi7
  39. 39. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ①延命パターン 17 objc   class objc   class objc   class Nullability,  Genericsに関するアノテーションを付加 型安全・nil  安全  な世界 swi7 安全にアクセス Objec<ve-­‐C swi7
  40. 40. ①延命パターン Copyright (C) DeNA Co.,Ltd. All Rights Reserved. objcに Nullability, Lightweight Genericsを追加する 18 @interface UserHistory -(Episode*)lastEepisode; -(NSArray*)allEpisodes; @end
  41. 41. ①延命パターン Copyright (C) DeNA Co.,Ltd. All Rights Reserved. objcに Nullability, Lightweight Genericsを追加する 18 @interface UserHistory -(Episode*)lastEepisode; -(NSArray*)allEpisodes; @end NS_ASSUME_NONNULL_BEGIN @interface UserHistory -(nullable Episode*)lastEepisode; -(NSArray<Episode*>*)allEpisodes; NS_ASSUME_NONNULL_END @end
  42. 42. ①延命パターン Copyright (C) DeNA Co.,Ltd. All Rights Reserved. objcに Nullability, Lightweight Genericsを追加する 18 @interface UserHistory -(Episode*)lastEepisode; -(NSArray*)allEpisodes; @end NS_ASSUME_NONNULL_BEGIN @interface UserHistory -(nullable Episode*)lastEepisode; -(NSArray<Episode*>*)allEpisodes; NS_ASSUME_NONNULL_END @end class UserHistory { func lastEepisode()->Episode? func allEepisodes()->[Episode] }
  43. 43. ①延命パターン Copyright (C) DeNA Co.,Ltd. All Rights Reserved. objcに Nullability, Lightweight Genericsを追加する • 既存のobjc資産を安全に使える • ローコスト・ハイリターン • Swift対応への第一歩として最適 18 @interface UserHistory -(Episode*)lastEepisode; -(NSArray*)allEpisodes; @end NS_ASSUME_NONNULL_BEGIN @interface UserHistory -(nullable Episode*)lastEepisode; -(NSArray<Episode*>*)allEpisodes; NS_ASSUME_NONNULL_END @end class UserHistory { func lastEepisode()->Episode? func allEepisodes()->[Episode] }
  44. 44. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ②ご新規パターン 19 Objec<ve-­‐C swi7
  45. 45. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ②ご新規パターン 19 objc   class objc   class objc   class Objec<ve-­‐C swi7
  46. 46. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ②ご新規パターン 19 objc   class objc   class objc   class ViewController   .swi7 View   Model   Objec<ve-­‐C swi7
  47. 47. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ②ご新規パターン 19 objc   class objc   class objc   class instan<ate ViewController   .swi7 View   Model   Objec<ve-­‐C swi7
  48. 48. ②ご新規パターン Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 新規ViewControllerは基本フルSwiftで書く 「新規開発分はSwiftで書きます」パターン 既存のobjcコードの依存が少なくやりやすい 新しい画面や機能を追加するケースにおすすめ 例) • ユーザ登録・ログイン • マイメニュー • コイン購入処理 • 動画広告 20
  49. 49. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 21 ③切り出しパターン Objec<ve-­‐C swi7
  50. 50. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 21 ③切り出しパターン objc  class   method   Objec<ve-­‐C swi7
  51. 51. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 21 ③切り出しパターン objc  class   method   Objec<ve-­‐C swi7
  52. 52. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 21 Logic   .swi7 ③切り出しパターン objc  class   method   Objec<ve-­‐C swi7
  53. 53. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 21 Logic   .swi7 ③切り出しパターン objc  class   method   コール Objec<ve-­‐C swi7
  54. 54. ③切り出しパターン Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ロジックをswiftに切り出す 22 - (NSNumber*)getNum { NSNumber* num = ...; return num; } .m
  55. 55. ③切り出しパターン Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ロジックをswiftに切り出す 22 if (num.integerValue == 0) { NSLog(@"num is zero"); } else { NSLog(@"num is non zero"); } - (NSNumber*)getNum { NSNumber* num = ...; return num; } .m
  56. 56. ③切り出しパターン Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ロジックをswiftに切り出す 22 - (NSNumber*)getNum { NSNumber* num = ...; return num; } .m
  57. 57. ③切り出しパターン Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ロジックをswiftに切り出す 22 - (NSNumber*)getNum { NSNumber* num = ...; return num; } .m [NumLogger debug:num];
  58. 58. ③切り出しパターン Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ロジックをswiftに切り出す 22 - (NSNumber*)getNum { NSNumber* num = ...; return num; } .m + final class NumLogger: NSObject { class func debug(num:NSNumber) { if num.integerValue == 0 { print("num is zero") } else { print("num is non zero") } } } .swi7 [NumLogger debug:num];
  59. 59. ③切り出しパターン Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ロジックをswiftに切り出す 22 - (NSNumber*)getNum { NSNumber* num = ...; return num; } .m + final class NumLogger: NSObject { class func debug(num:NSNumber) { if num.integerValue == 0 { print("num is zero") } else { print("num is non zero") } } } .swi7 [NumLogger debug:num]; • 最小限の変更で既存objcメソッドのロジックを追加・修正できる • 使いどころ:ログ出力処理、バリデーション、Util的な処理 • ユニットテストも書きやすい
  60. 60. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ④ブリッジパターン 23 Objec<ve-­‐C swi7
  61. 61. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ④ブリッジパターン 23 objc   class objc   class objc   class Objec<ve-­‐C swi7
  62. 62. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ④ブリッジパターン 23 Nested  Type Top-­‐level   func<on Typealias Tuple enumenumenum structstructstruct objc   class objc   class objc   class Objec<ve-­‐C swi7
  63. 63. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ④ブリッジパターン 23 Nested  Type Top-­‐level   func<on Typealias Tuple enumenumenum structstructstruct objc   class objc   class objc   class Objec<ve-­‐C swi7
  64. 64. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ④ブリッジパターン 23 Nested  Type Top-­‐level   func<on Typealias Tuple enumenumenum structstructstruct objc   class objc   class objc   class Objec<ve-­‐C swi7
  65. 65. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ④ブリッジパターン 23 Nested  Type Top-­‐level   func<on Typealias Tuple enumenumenum structstructstruct objc   class objc   class objc   class Bridging   NSObject Objec<ve-­‐C swi7
  66. 66. objcとswiftの橋渡し 一定規模のswfitコンポーネント objcコード の橋渡し ④ブリッジパターン Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 24 広告枠 Ad networking logging imp click display/   event  handling
  67. 67. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 25 ⑤extensionパターン Objec<ve-­‐C swi7
  68. 68. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 25 ⑤extensionパターン FooClass   method1 method2 Objec<ve-­‐C swi7
  69. 69. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 25 ⑤extensionパターン FooClass   method1 method2 method3 Objec<ve-­‐C swi7
  70. 70. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 25 ⑤extensionパターン FooClass   method1 method2 method3 FooClass   extension     Objec<ve-­‐C swi7
  71. 71. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 25 ⑤extensionパターン FooClass   method1 method2 method3 FooClass   extension     method3 Objec<ve-­‐C swi7
  72. 72. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 25 ⑤extensionパターン FooClass   method1 method2 method3 FooClass   extension     method3 Objec<ve-­‐C swi7
  73. 73. ⑤extensionパターン Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 既存objcクラスをextensionする 26 @implement FooClass - (void)method1 {...} - (void)method2 {...} @end .m
  74. 74. ⑤extensionパターン Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 既存objcクラスをextensionする 26 @implement FooClass - (void)method1 {...} - (void)method2 {...} @end .m + extension FooClass { //メソッド追加 func method3() { … } } .swi7
  75. 75. ⑤extensionパターン Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 既存objcクラスをextensionする 26 @implement FooClass - (void)method1 {...} - (void)method2 {...} @end .m + extension FooClass { //メソッド追加 func method3() { … } } .swi7 • 一番自然で適用させやすいパターン
  76. 76. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 27 ⑤extensionパターン ViewerController Objec<ve-­‐C swi7
  77. 77. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 27 ⑤extensionパターン ViewerController Objec<ve-­‐C swi7
  78. 78. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 27 ⑤extensionパターン ViewerController Objec<ve-­‐C swi7
  79. 79. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 27 ⑤extensionパターン ViewerController ViewerController   extension Objec<ve-­‐C swi7
  80. 80. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 27 ⑤extensionパターン ViewerController ViewerController   extension func   shareBu)onDidTapped()   Objec<ve-­‐C swi7
  81. 81. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 27 ⑤extensionパターン ViewerController ViewerController   extension func   shareBu)onDidTapped()   Objec<ve-­‐C swi7
  82. 82. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 28 ⑥暴露パターン Objec<ve-­‐C swi7
  83. 83. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 28 ⑥暴露パターン FooClass   property1 method1 Objec<ve-­‐C swi7
  84. 84. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 28 ⑥暴露パターン FooClass   property1 method1 Objec<ve-­‐C swi7 method2
  85. 85. FooClass   extension     ⑤extensionパターン Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 28 ⑥暴露パターン FooClass   property1 method1 Objec<ve-­‐C swi7 method2
  86. 86. FooClass   extension     ⑤extensionパターン Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 28 ⑥暴露パターン FooClass   property1 method1 Objec<ve-­‐C swi7 method2   method2
  87. 87. FooClass   extension     ⑤extensionパターン Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 28 ⑥暴露パターン FooClass   property1 method1 参照・コール不可 Objec<ve-­‐C swi7 method2   method2
  88. 88. FooClass   extension     ⑤extensionパターン Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 28 ⑥暴露パターン FooClass   property1 method1 Objec<ve-­‐C swi7 method2   method2
  89. 89. FooClass   extension     ⑤extensionパターン Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 28 ⑥暴露パターン FooClass   property1 method1 Objec<ve-­‐C swi7 method2   method2 意図的な   カプセル化の破壊!
  90. 90. FooClass   extension     ⑤extensionパターン Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 28 ⑥暴露パターン FooClass   property1 method1 Bridging-­‐ Header.h   Objec<ve-­‐C swi7 method2   method2 意図的な   カプセル化の破壊!
  91. 91. FooClass   extension     ⑤extensionパターン Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 28 ⑥暴露パターン FooClass   property1 method1 Bridging-­‐ Header.h   Objec<ve-­‐C swi7 property1 method1 公開 method2   method2 意図的な   カプセル化の破壊!
  92. 92. FooClass   extension     ⑤extensionパターン Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 28 ⑥暴露パターン FooClass   property1 method1 Bridging-­‐ Header.h   参照・コール Objec<ve-­‐C swi7 property1 method1 公開 method2   method2 意図的な   カプセル化の破壊!
  93. 93. ⑥暴露パターン Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 29 @interface FooClass () @property NSString property1; @end @implement FooClass (void)method1 { ... } @end .m @interface FooClass @end .h
  94. 94. ⑥暴露パターン Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 29 @interface FooClass () @property NSString property1; @end @implement FooClass (void)method1 { ... } @end .m #import “xxx.h” #import “yyy.h” #import “zzz.h” ... @interface FooClass (PrivateForSwift) @property (readonly) NSString *property1; (void)method1; @end Xxxx-­‐Bridging-­‐Header.h + @interface FooClass @end .h
  95. 95. ⑥暴露パターン Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 29 @interface FooClass () @property NSString property1; @end @implement FooClass (void)method1 { ... } @end .m extension FooClass { func methods() { property1 = “foo"; method1() } } .swi7 + #import “xxx.h” #import “yyy.h” #import “zzz.h” ... @interface FooClass (PrivateForSwift) @property (readonly) NSString *property1; (void)method1; @end Xxxx-­‐Bridging-­‐Header.h + @interface FooClass @end .h
  96. 96. ⑥暴露パターン Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 29 @interface FooClass () @property NSString property1; @end @implement FooClass (void)method1 { ... } @end .m extension FooClass { func methods() { property1 = “foo"; method1() } } .swi7 + #import “xxx.h” #import “yyy.h” #import “zzz.h” ... @interface FooClass (PrivateForSwift) @property (readonly) NSString *property1; (void)method1; @end Xxxx-­‐Bridging-­‐Header.h + @interface FooClass @end .h ↑objcは一切変更していない
  97. 97. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 30 プライベート属性を部分的に公開する ⑥暴露パターン
  98. 98. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 意図的にカプセル化を破壊 30 プライベート属性を部分的に公開する ⑥暴露パターン
  99. 99. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 意図的にカプセル化を破壊 ⁃ extensionから本体クラスのプライベート属性へのアクセスが 可能に 30 プライベート属性を部分的に公開する ⑥暴露パターン
  100. 100. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 意図的にカプセル化を破壊 ⁃ extensionから本体クラスのプライベート属性へのアクセスが 可能に ⁃ 変更箇所はブリッジングヘッダのみ、既存の.h/.mは変更なし 30 プライベート属性を部分的に公開する ⑥暴露パターン
  101. 101. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 意図的にカプセル化を破壊 ⁃ extensionから本体クラスのプライベート属性へのアクセスが 可能に ⁃ 変更箇所はブリッジングヘッダのみ、既存の.h/.mは変更なし 妥協が必要な部分 30 プライベート属性を部分的に公開する ⑥暴露パターン
  102. 102. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 意図的にカプセル化を破壊 ⁃ extensionから本体クラスのプライベート属性へのアクセスが 可能に ⁃ 変更箇所はブリッジングヘッダのみ、既存の.h/.mは変更なし 妥協が必要な部分 ⁃ 異論の出るところ 30 プライベート属性を部分的に公開する ⑥暴露パターン
  103. 103. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 意図的にカプセル化を破壊 ⁃ extensionから本体クラスのプライベート属性へのアクセスが 可能に ⁃ 変更箇所はブリッジングヘッダのみ、既存の.h/.mは変更なし 妥協が必要な部分 ⁃ 異論の出るところ ⁃ 一時的な対応、という割り切り 30 プライベート属性を部分的に公開する ⑥暴露パターン
  104. 104. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 意図的にカプセル化を破壊 ⁃ extensionから本体クラスのプライベート属性へのアクセスが 可能に ⁃ 変更箇所はブリッジングヘッダのみ、既存の.h/.mは変更なし 妥協が必要な部分 ⁃ 異論の出るところ ⁃ 一時的な対応、という割り切り ⁃ ここを割り切ればSwift化は一気に進む 30 プライベート属性を部分的に公開する ⑥暴露パターン
  105. 105. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 31 ⑦乗っ取りパターン FooClass   method1 property1 31 Objec<ve-­‐C swi7 property2 method2
  106. 106. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 31 ⑦乗っ取りパターン FooClass   method1 property1 31 Objec<ve-­‐C swi7 property2 method2 FooClass   extension   method2   property2   ⑤extensionパターン???
  107. 107. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 31 ⑦乗っ取りパターン FooClass   method1 property1 31 Objec<ve-­‐C swi7 property2 method2 FooClass   extension   method2   property2   ⑤extensionパターン???
  108. 108. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 32 ⑦乗っ取りパターン 32 Objec<ve-­‐C swi7
  109. 109. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 32 ⑦乗っ取りパターン FooClass   method1 property1 32 Objec<ve-­‐C swi7
  110. 110. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 32 ⑦乗っ取りパターン FooClass   method1 property1 32 Objec<ve-­‐C swi7 property2 method2
  111. 111. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 32 ⑦乗っ取りパターン FooClass   method1 property1 32 Objec<ve-­‐C swi7 property2 method2 FooClassBaserename
  112. 112. FooClass   Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 32 ⑦乗っ取りパターン FooClass   method1 property1 32 Objec<ve-­‐C swi7 property2 method2 FooClassBaserename
  113. 113. FooClass   extends Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 32 ⑦乗っ取りパターン FooClass   method1 property1 32 Objec<ve-­‐C swi7 property2 method2 FooClassBaserename
  114. 114. FooClass   extends Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 32 ⑦乗っ取りパターン FooClass   method1 property1 32 method2   property2   Objec<ve-­‐C swi7 property2 method2 FooClassBaserename
  115. 115. FooClass   extends Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 32 ⑦乗っ取りパターン FooClass   method1 property1 32 method2   property2   Objec<ve-­‐C swi7 FooClassBaserename
  116. 116. FooClass   extends Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 32 ⑦乗っ取りパターン FooClass   method1 property1 32 method2   property2   Objec<ve-­‐C swi7 参照・コール? FooClassBaserename
  117. 117. FooClass   extends Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 32 ⑦乗っ取りパターン FooClass   method1 property1 32 method2   property2   Objec<ve-­‐C swi7 FooClassBaserename
  118. 118. FooClass   extends Bridging-­‐ Header.h   +⑥暴露パターン Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 32 ⑦乗っ取りパターン FooClass   method1 property1 32 method2   property2   Objec<ve-­‐C swi7 FooClassBaserename
  119. 119. FooClass   extends Bridging-­‐ Header.h   +⑥暴露パターン Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 32 ⑦乗っ取りパターン FooClass   method1 property1 32 method2   property2   Objec<ve-­‐C swi7 property1 method1 公開 FooClassBaserename
  120. 120. FooClass   extends Bridging-­‐ Header.h   +⑥暴露パターン Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 32 ⑦乗っ取りパターン FooClass   method1 property1 32 method2   property2   Objec<ve-­‐C swi7 property1 method1 公開 参照・コール FooClassBaserename
  121. 121. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 33 objクラスをswiftで継承し名前を乗っ取る ⑦乗っ取りパターン
  122. 122. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ⁃ 継承して乗っ取る 33 objクラスをswiftで継承し名前を乗っ取る ⑦乗っ取りパターン
  123. 123. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ⁃ 継承して乗っ取る • クラス本体をSwiftに移し替え、既存objcクラスは親 クラス化 33 objクラスをswiftで継承し名前を乗っ取る ⑦乗っ取りパターン
  124. 124. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ⁃ 継承して乗っ取る • クラス本体をSwiftに移し替え、既存objcクラスは親 クラス化 • プロパティやメソッドは自由に追加可能 33 objクラスをswiftで継承し名前を乗っ取る ⑦乗っ取りパターン
  125. 125. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ⁃ 継承して乗っ取る • クラス本体をSwiftに移し替え、既存objcクラスは親 クラス化 • プロパティやメソッドは自由に追加可能 • ⑥暴露パターンの併用可能 33 objクラスをswiftで継承し名前を乗っ取る ⑦乗っ取りパターン
  126. 126. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ⁃ 継承して乗っ取る • クラス本体をSwiftに移し替え、既存objcクラスは親 クラス化 • プロパティやメソッドは自由に追加可能 • ⑥暴露パターンの併用可能 ⁃ 妥協ポイント 33 objクラスをswiftで継承し名前を乗っ取る ⑦乗っ取りパターン
  127. 127. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ⁃ 継承して乗っ取る • クラス本体をSwiftに移し替え、既存objcクラスは親 クラス化 • プロパティやメソッドは自由に追加可能 • ⑥暴露パターンの併用可能 ⁃ 妥協ポイント • 継承関係が変更される 33 objクラスをswiftで継承し名前を乗っ取る ⑦乗っ取りパターン
  128. 128. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ⁃ 継承して乗っ取る • クラス本体をSwiftに移し替え、既存objcクラスは親 クラス化 • プロパティやメソッドは自由に追加可能 • ⑥暴露パターンの併用可能 ⁃ 妥協ポイント • 継承関係が変更される ⁃ 別解→ 33 objクラスをswiftで継承し名前を乗っ取る ⑦乗っ取りパターン
  129. 129. FooClass   method1 property1 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 34 ⑦別解:乗っ取りパターン(カテゴリ拡張) FooClass   34 property2   (Category  Extension) Objec<ve-­‐C swi7 property1 extensionではなく   同名クラスをSwi7で 元のFooClassを   objcカテゴリ拡張に降格
  130. 130. FooClass   method1 property1 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 34 ⑦別解:乗っ取りパターン(カテゴリ拡張) FooClass   34 property2   (Category  Extension) Objec<ve-­‐C swi7 property1 extensionではなく   同名クラスをSwi7で 元のFooClassを   objcカテゴリ拡張に降格 ☓乗っ取り元objcにプライベート属性がある場合、制限多めなのでNG
  131. 131. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 参考:アンチパターン 35 //ストアドプロパティの追加 var name:String { get { return objc_getAssociatedObject(self, &key) as! String } set { objc_setAssociatedObject(self, &key, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)} } //プライベートメソッドの実行 if respondsToSelector("_reload") { performSelector("_reload") } //プライベートプロパティの参照 if let titleLabel = valueForKey("TitleLabel") as? UILabel { ... } • カプセル化を破壊せずにプライベート 属性を参照・追加可能   • メンテナンス性△   • マンガボックスでは極力使用しないよ うにしている associatedObject キー値コーディング objcセレクター
  132. 132. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 36 ⑧写経パターン Objec<ve-­‐C swi7
  133. 133. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 36 FooClass   method1 method2 ⑧写経パターン Objec<ve-­‐C swi7
  134. 134. 写経 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 36 FooClass   method1 method2 ⑧写経パターン Objec<ve-­‐C swi7
  135. 135. FooClass   method1 method2 写経 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 36 FooClass   method1 method2 ⑧写経パターン Objec<ve-­‐C swi7
  136. 136. FooClass   method1 method2 写経 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 36 ⑧写経パターン Objec<ve-­‐C swi7
  137. 137. FooClass   method1 method2 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 36 ⑧写経パターン Objec<ve-­‐C swi7
  138. 138. ⑧写経パターン Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 既存のobjcコードをswiftで書き直す • 最後の手段 • テストの有無でリスク変動 • 元コードがテストで保護されている→◎ • 対象objcコードをまずテストで保護してからSwiftで書き直す→⃝ • 完全書き直し→△ • ある意味シンプルだが、フルQAは必須、コスト大 37
  139. 139. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 参考:写経のお供に 38 • Generated Interface
  140. 140. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 参考:写経のお供に 39 • Generated Interface
  141. 141. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 参考:写経のお供に 40 • Generated Interface
  142. 142. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 参考:写経のお供に • objc→swift コード変換ツール • https://github.com/yahoojapan/objc2swift • https://objectivec2swift.com/?ref=producthunt#/converter/code • http://iswift.org • https://myappconverter.com • https://itunes.apple.com/us/app/o2swift-objective-c-to-swift/id1060352413?ls=1&mt=12 • いずれも機械的な変換なので手直し&QAは必須 41
  143. 143. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 42 ① 延命パターン ② ご新規パターン ③ 切り出しパターン ④ ブリッジパターン ⑤ extensionパターン ⑥ 暴露パターン ⑦ 乗っ取りパターン ⑧ 写経パターン Mix-and-Matchを使ったSwift移行パターン リスク   トリッキー度   Swi7移行度 小 大
  144. 144. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 何かに似ている 43
  145. 145. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 何かに似ている 44 ① 延命パターン ② ご新規パターン ③ 切り出しパターン ④ ブリッジパターン ⑤ extensionパターン ⑥ 暴露パターン ⑦ 乗っ取りパターン ⑧ 写経パターン
  146. 146. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 何かに似ている 44 ① 延命パターン ② ご新規パターン ③ 切り出しパターン ④ ブリッジパターン ⑤ extensionパターン ⑥ 暴露パターン ⑦ 乗っ取りパターン ⑧ 写経パターン h)p://shop.ohmsha.co.jp/shopdetail/000000003881/ リファクタリング
  147. 147. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 何かに似ている 44 ① 延命パターン ② ご新規パターン ③ 切り出しパターン ④ ブリッジパターン ⑤ extensionパターン ⑥ 暴露パターン ⑦ 乗っ取りパターン ⑧ 写経パターン h)p://shop.ohmsha.co.jp/shopdetail/000000003881/ リファクタリング Extract  Method   Extract  Class
  148. 148. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 何かに似ている 45 ① 延命パターン ② ご新規パターン ③ 切り出しパターン ④ ブリッジパターン ⑤ extensionパターン ⑥ 暴露パターン ⑦ 乗っ取りパターン ⑧ 写経パターン
  149. 149. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 何かに似ている 45 ① 延命パターン ② ご新規パターン ③ 切り出しパターン ④ ブリッジパターン ⑤ extensionパターン ⑥ 暴露パターン ⑦ 乗っ取りパターン ⑧ 写経パターン h)p://www.sbcr.jp/products/4797311126.html gof  デザインパターン
  150. 150. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 何かに似ている 45 ① 延命パターン ② ご新規パターン ③ 切り出しパターン ④ ブリッジパターン ⑤ extensionパターン ⑥ 暴露パターン ⑦ 乗っ取りパターン ⑧ 写経パターン h)p://www.sbcr.jp/products/4797311126.html gof  デザインパターン Bridgeパターン
  151. 151. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 何かに似ている 46 ① 延命パターン ② ご新規パターン ③ 切り出しパターン ④ ブリッジパターン ⑤ extensionパターン ⑥ 暴露パターン ⑦ 乗っ取りパターン ⑧ 写経パターン
  152. 152. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 何かに似ている 46 ① 延命パターン ② ご新規パターン ③ 切り出しパターン ④ ブリッジパターン ⑤ extensionパターン ⑥ 暴露パターン ⑦ 乗っ取りパターン ⑧ 写経パターン h)p://www.shoeisha.co.jp/book/detail/9784798116839 レガシーコード改善ガイド
  153. 153. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 何かに似ている 46 ① 延命パターン ② ご新規パターン ③ 切り出しパターン ④ ブリッジパターン ⑤ extensionパターン ⑥ 暴露パターン ⑦ 乗っ取りパターン ⑧ 写経パターン h)p://www.shoeisha.co.jp/book/detail/9784798116839 レガシーコード改善ガイド • スプラウトメソッド   • スプラウトクラス   • 静的メソッドの公開 テストコードを書くためのリファクタリング手法
  154. 154. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 47 ① 延命パターン ② ご新規パターン ③ 切り出しパターン ④ ブリッジパターン ⑤ extensionパターン ⑥ 暴露パターン ⑦ 乗っ取りパターン ⑧ 写経パターン Mix-and-Matchを使ったSwift移行パターン 既存のソフトウェア開発技法の活用により   スムーズ・安全にSwi7移行可能
  155. 155. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. まとめ 48
  156. 156. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. まとめ 49
  157. 157. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. まとめ Objective-CからSwift化への移行は大変? 49
  158. 158. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. まとめ Objective-CからSwift化への移行は大変? →まずは簡単なパターンから試してみる 49
  159. 159. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. まとめ Objective-CからSwift化への移行は大変? →まずは簡単なパターンから試してみる • 延命パターン 49
  160. 160. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. まとめ Objective-CからSwift化への移行は大変? →まずは簡単なパターンから試してみる • 延命パターン • ご新規パターン 49
  161. 161. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. まとめ Objective-CからSwift化への移行は大変? →まずは簡単なパターンから試してみる • 延命パターン • ご新規パターン 慣れてきたらいろんなパターンを試す 49
  162. 162. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. まとめ Objective-CからSwift化への移行は大変? →まずは簡単なパターンから試してみる • 延命パターン • ご新規パターン 慣れてきたらいろんなパターンを試す パターンについてあれこれ考えるのも楽しい 49
  163. 163. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. まとめ Objective-CからSwift化への移行は大変? →まずは簡単なパターンから試してみる • 延命パターン • ご新規パターン 慣れてきたらいろんなパターンを試す パターンについてあれこれ考えるのも楽しい ⁃ 他にも良いパターンがありそう 49
  164. 164. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. まとめ Objective-CからSwift化への移行は大変? →まずは簡単なパターンから試してみる • 延命パターン • ご新規パターン 慣れてきたらいろんなパターンを試す パターンについてあれこれ考えるのも楽しい ⁃ 他にも良いパターンがありそう ⁃ かっこいい名前希望 49
  165. 165. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 50 objc
  166. 166. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 50 objc
  167. 167. swi7 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 50 objc
  168. 168. swi7 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 51 objc
  169. 169. swi7 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 52 objc swi7
  170. 170. swi7 swi7 swi7 swi7 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 53 objc swi7 swi7
  171. 171. objc swi7 swi7 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 54 swi7swi7 swi7 swi7swi7 swi7
  172. 172. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 55 swi7
  173. 173. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 56 進 捗 ど う で す か
  174. 174. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. マンガボックスの現在のSwift化率 17%程度 まだまだこれから 57
  175. 175. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 今後の予測(雑) 58 2020年  ver5.6  にてSwi7化率100%到達予定(雑)!!!
  176. 176. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 59 Let’s Objc to Swift !
  177. 177. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ありがとうございました。 60

×