can we live in a pure swift world?
TRANSCRIPT
About
渋谷のVOYAGE GROUPでiOSエンジニアをしています。Twi$er: @TachibanaKaoruBlog : h$p://www.toyship.org/
@TachibanaKaoru, 2015 2
VOYAGE GROUP
• appe%というグルメアプリや、朝時間.jpという朝時間活用アプリなどをだしてます。
• iOS/Android Engineer絶賛募集中です。
• h5p://voyagegroup.com/crew/recruit/career/android/
• Kotlinで開発してます
@TachibanaKaoru, 2015 3
try! Swi)• 2016/3/2~3/4 at Shibuya
• h3p://tryswi9conf.com/
• VOYAGE GROUP はtry Swi9のスポンサーです。
@TachibanaKaoru, 2015 4
iOS Developers Conference 2016• h#ps://iosdc.jp
• iOSおよび周辺技術を題材とした日本国内初の Developer
Conference です。
• 2016/08/20
• スポンサーを募集しています
@TachibanaKaoru, 2015 5
Unusable Swi- features in ObjC (1)• Generics
• Tuples
• Enumera0ons defined in Swi7 without Int raw value type
• Structures defined in Swi7
• Top-level func0ons defined in Swi7
• Global Variables defined in Swi7
@TachibanaKaoru, 2015 11
Unusable Swi- features in ObjC (2)• Typealiases defined in Swi0
• Swi0-style variadics
• Nested types
• Curried func:ons
• Protocol Extension (new from Swi02.0)
@TachibanaKaoru, 2015 12
These are not only unusable from ObjC• これらの Swi&独自機能は「Objec,ve-Cからよべない」だけではない
• 実は、pure Swi& の project でもこの制限がかかる
@TachibanaKaoru, 2015 13
We cannot use them as a selector• Objec've-Cでよべないものはselectorで指定することができない
• performselector 指定することもできない。
• Add-Target 指定することもできない。
@TachibanaKaoru, 2015 14
Ex: Tuples as Selector• compile OK, unrecognized selector
let mybutton = UIButton(type: UIButtonType.Custom)mybutton.addTarget(self, action: "currentStatus:", forControlEvents: UIControlEvents.TouchUpInside)
func presonInformation(sender:AnyObject) -> (name:String,age:Int) { return ("Ranko Kanzaki",14)}
@TachibanaKaoru, 2015 15
Ex: String Enum as Selector• compile OK, unrecognized selector
let mybutton = UIButton(type: UIButtonType.Custom)mybutton.addTarget(self, action: "currentStatus:", forControlEvents: UIControlEvents.TouchUpInside)
enum GameStatus { case Start case End}func currentStatus(sender:AnyObject) -> GameStatus{ return GameStatus.Start}
@TachibanaKaoru, 2015 16
Ex: Protocol Extension as Selector• compile OK, unrecognized selector
let mybutton = UIButton(type: UIButtonType.Custom)mybutton.addTarget(self, action: "currentStatus:", forControlEvents: UIControlEvents.TouchUpInside)
protocol DebugLog { func writeDebugMessage() -> Void}extension DebugLog { func writeDebugMessage() -> Void{ print("Protocol extensionで共通化されたデバッグ出力です。") }}
@TachibanaKaoru, 2015 17
Same for @nonobjc• @nonobjc は、Objec+ve-Cと互換性のあるSwi2 featureにつけるとObjec+ve-Cから使えなくなる指定子(@objcの逆)
• compile OK, unrecognized selector
let mybutton = UIButton(type: UIButtonType.Custom)mybutton.addTarget(self, action: "currentHP:", forControlEvents: UIControlEvents.TouchUpInside)
@nonobjcfunc currentHP(sender:AnyObject) -> Int{ return 0}
@TachibanaKaoru, 2015 18
We cannot use Swi.-only features as a selector
• 「Objec've-Cからよべないもの」は、selectorに指定できない
@TachibanaKaoru, 2015 19
What "usable from ObjC" means?• 「Objec've-Cからよべる」とは?
• Swi. Compile 時に作成される Objec've-C member table に入っているかどうか
@TachibanaKaoru, 2015 20
Objec&ve-C member table• h#ps://github.com/apple/swi5/blob/master/lib/AST/NameLookup.cpp
void ClassDecl::createObjCMethodLookup() { assert(!ObjCMethodLookup && "Already have an Objective-C member table"); auto &ctx = getASTContext(); ObjCMethodLookup = new (ctx) ObjCMethodLookupTable();
// Register a cleanup with the ASTContext to call the lookup table // destructor. ctx.addCleanup([this]() { this->ObjCMethodLookup->destroy(); });}
@TachibanaKaoru, 2015 21
Is this method "usable from ObjC" ?
• 実装時に、特定のメソッドがObjec've-Cから使えるのかどうか確認するのであれば、MyProject-Swi4.hで確認しましょう
• ビルド時に中間生成物として作成されています
• Xcodeでは右の方法で見ることができます
@TachibanaKaoru, 2015 22
In "MyProject-Swi2.h"• ObjC signature
• Protocol ExtensionのsignatureはadoptしているclassではないSWIFT_PROTOCOL("_TtP6Forest8DebugLog_")@protocol DebugLog- (void)writeDebugMessage;@end
SWIFT_CLASS("_TtC6Forest17ElmViewController")@interface ElmViewController : UIViewController <UINavigationControllerDelegate>- (void)viewWillAppear:(BOOL)animated;- (void)viewDidDisappear:(BOOL)animated;- (void)showTestMessage:(NSString * __nullable)message;- (nonnull instancetype)initWithNibName:(NSString * __nullable)nibNameOrNil bundle:(NSBundle * __nullable)nibBundleOrNil OBJC_DESIGNATED_INITIALIZER;- (nullable instancetype)initWithCoder:(NSCoder * __nonnull)aDecoder OBJC_DESIGNATED_INITIALIZER;@end
@TachibanaKaoru, 2015 23