Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Swift on the ObjC #shibuyaswift
Search
ainame
June 08, 2016
Programming
930
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Swift on the ObjC #shibuyaswift
ainame
June 08, 2016
More Decks by ainame
See All by ainame
Swift 5.7で変わる正規表現を試してみよう
ainame
4
7.9k
iOSDC 2021 - App Store用スクリーンショットの自動生成をアラビア語対応してSwiftUIで実装してみた
ainame
0
6k
DNN/GPU with Ruby #rubykaigi
ainame
2
3.3k
Server Side Swift実用性評価 2017 #iosdc #b
ainame
3
4.5k
Process tons of jobs with Swift
ainame
0
1.9k
家族アルバムみてね 開発風景 #realm_jp
ainame
4
4.2k
iOSで無限バックグラウンドアップロード(に挑戦してみた話)
ainame
2
5.3k
リファクタリングとtsort
ainame
1
1.8k
RubyMotionについて #mixiwwdc
ainame
2
470
Other Decks in Programming
See All in Programming
JPUG勉強会 OSSデータベースの内部構造を理解しよう(第2回)
oga5
0
260
WebMCP Challenge に星空観察アプリで参加した話
okajun35
0
180
技術的負債を組織課題として解く-増えすぎたマイクロサービスとの戦い-
reimaru
1
2.1k
巨大モノリシックアプリ モダン化大作戦
ktcryomm
1
1.1k
フロントエンドUIフレームワークのこれまでとこれから
ssssota
5
2.9k
AI活用は、個人から組織へ|マルチプレイヤーエージェントハーネス「QM」の社内活用事例 / AI use is moving from individuals to orgs
rkaga
1
130
Java 27新機能 / Java 27 new features
kishida
2
150
SREの越境 / SRE Collaboration
y0hgi
2
260
Webの地図
yosuke_furukawa
PRO
6
4.7k
App Intentsのビルドプロセスを支える技術
kntkymt
0
410
AWS DevOps Agentで インシデント対応をAIに任せたい
honmarkhunt
7
3k
Security issues being discussed on Web Platforms
petamoriken
0
1k
Featured
See All Featured
Building Applications with DynamoDB
mza
96
7.2k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
The agentic SEO stack - context over prompts
schlessera
0
940
Building a Scalable Design System with Sketch
lauravandoore
464
34k
Leo the Paperboy
mayatellez
10
2.3k
Site-Speed That Sticks
csswizardry
13
1.5k
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
2
430
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
240
Designing for Performance
lara
611
70k
The SEO identity crisis: Don't let AI make you average
varn
0
560
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Mobile First: as difficult as doing things right
swwweet
225
10k
Transcript
Swift on the ObjC Shibuya.swift#4 • @ainame (Satoshi NAMAI) •
株式会社ミクシィ • 家族アルバムみてね作ってます
Question あなたのプロジェクトにはまだObjective-Cのコードがありますか?
Contents みてねチームにおいて、昨年10月頃からObjCで書かれたコードベースの上にSwift を書いてきた際に取り組んできたことを話します。
Policy ユーザーへの価値提供が第一 • 全コードを一気にSwiftに置き換えることはしない • 新規に書く箇所はSwift • 大きく仕様変更が入る際には画面単位でSwiftに置き換えつつ レガシーな設計から良い設計に合わせていく
Study Swift by WWDC videos 毎週水曜にランチタイムにみんなで動画を見てSwift2について学んだ • What's New in
Swift • Protocol-Oriented Programming in Swift • Building Better Apps with Value Types in Swift • Swift and Objective-C Interoperability see: 動画で学ぶモダンなiOS/Androidアプリ開発技術 - ainameの日記 井戸端iOS飯で過去に見た動画まとめ
Get started! • Bridging HeaderでObjCのコードをimportしてSwiftを書き始める • SwiftのStructやEnumはObjC側では使えないのでほとんど使わず、NSObject を継承 or @objcでClassを書いてく
• ObjCの巨大なViewControllerに機能追加する際には同じファイル名で extensionとして実装(⌥ + ↑ で切り替え可能) ◦ SomeViewController.{h,m,swift}という感じで3ファイルが存在している状態
Xcode’s auto-completion •Swift上でObjcのクラスの補完が効かなくなった Clean、Derived Data削除も効果なし importの仕方を修正したら復活 ✖ #import <GAI.h> ◯
#import <GoogleAnalytics/GAI.h> see: http://stackoverflow.com/a/35431971
Swifty? • さらに動画でSwiftっぽい書き方を学ぶ • "Feet in Both Worlds: From Objective-C
to Swift" by Andy Matuschak • Let's Play: Refactor the Mega Controller!
Example // enumを使ってUIの機能追加したい enum Icon { case Color(UIColor) case Image(UIImage)
} class IconView: UIView { init(icon: Icon) { … } } // ObjC用の箱を用意しておく class Box<T> { let value: T init(_ value: T) { self.value = value } } // ObjCのクラスには箱だけを id型としておいておく @interface LegacyViewController @property (readwrite, strong) id /* Box<SomeEnum> */ _icon; @end // 箱から取り出し用の propertyを宣言して extension LegacyViewController { var icon: Icon { get { return (_icon as! Box<Icon>).value } set { _icon = Box(newValue) } } // すっきりした実装ができる func showProfileWithIcon(icon: Icon) } どうしてもSwiftでしか使えないやつをObjCのViewControllerに もたせたい場合はBoxパターンを利用
Nullability & Lightweight Generics • SwiftでObjCのメソッドを呼ぶ際にNullabilityを考慮してなくて事故る • Bridging Headerでimportされているものには必ずNullability +
Lightweight Genericsを指定するルールに
Nullability & Lightweight Generics - Pitfall SwiftからObjCに公開するメソッドはnilが入り込みやすい (Swift側で参照すると落ちる) @objc func
doSomething(string: String) ← 普通のSwiftのメソッ ド---------------------------------------------------------- NSString *str = [self textField.text]; ← TextFieldからnullableなNSStringをとる [obj doSomething:str]; ← Swiftのメソッドにnullableなやつ渡す❌
Carthage & Dynamic Framework • SwiftベースのライブラリはDynamic Frameworkとして取り込んでいる • Cocoapodsはuse_frameworks!できなかった時ように残してある (当時GoogleAnalytics
SDKとか出来なかったけど今は対応している?) • carthage bootstrapは初回こそ時間かかるものの一度ビルドすると再ビルドせ ず済むので良い • CircleCI上でRxSwiftのビルド終わらない問題 ◦ CI上でビルドせず最初から s3にビルド済みキャッシュを自前で置く戦略で・・・ ◦ aws s3 sync s3://BUCKET/`md5 Cartfile.resolved | awk '{ print $4; }'` Carthage/Build/iOS
Introduce swifty libraries 置き換え系 • SDWebImageから拝借したdispatch_sync_main_safe -> duemunk/Async • DateTools
-> malcommac/SwiftDate • PromiseKit & KVOController -> ReactiveX/RxSwift 新規導入系 • antitypical/Result, lyft/mapper, ra1028/Former
NSCoding & Unit testing シリアライズ処理は辛い(怖い) • @objc(CLASS NAME)を利用してSwift化 • Module名が異なるとクラス名が一緒でもforce
downcastでクラッシュ 1. テスト対象クラスをTestのTargetにも追加 2. TestのtargetのModule名をアプリのTargetのModule名にして回避 • アプリのTargetをModule化して@testable importする方が一般的っぽい?
Example @interface MTNFoo: NSObject<NSCoding> @property(nonatomic) MTNBar *bar; .... @end @implementation
MTNFoo - (instancetype)initWithCoder:(NSCoder *)aDecoder { self = [self init]; if (self) { _bar= [aDecoder ecodeObjectForKey:@"bar"]; } return self } @end @objc(MTNFoo) class MTNFoo: NSObjcet, NSCoding { var bar:MTNBar … required init?(coder aDecoder: NSCoder) { self.bar = aDecoder.decodeObjectForKey("bar") as! MTNBar } } MiteneTests -> Mitene Could not cast value of type MiteneTests.MTNBar' (0x13218604) to 'Mitene.MTNBar'
SwiftLint • SwiftLintをフォーマッター的に利用 • まだレビュー用途には利用できてない • チームメンバーがXcodePlugin書いてくれた ◦ ypresto/SwiftLintXcode: An
Xcode plug-in to format your code using SwiftLint.
Current Status まだまだこれから
まとめ • Swiftに慣れるのにみんなで動画を見るのはいいぞ • Nullability頑張って定義していこう • Xcodeの補完効かなくなると仕事出来なくなるので頑張って解決しよう • ObjCと混ぜたプロジェクトでテスト書くの大変っぽい?
Enjoy Swift! See you next week at WWDC!