$30 off During Our Annual Pro Sale. View Details »

Swiftのアプリ開発でハマったこと

 Swiftのアプリ開発でハマったこと

XCode6 Beta でSwiftで開発したときにあったトラブルを紹介します

yohei sugigami

July 17, 2014
Tweet

More Decks by yohei sugigami

Other Decks in Technology

Transcript

  1. Swift LT
    @Wantedly
    2014-07-17 yohei sugigami

    View Slide

  2. ਿ্༸ฏ εΪΨϛϤ΢ϔΠ

    (JU)VC!TVTJFZZ
    ઌ݄+0*/ͨ͠͹͔Γͷ৽ถϓϩάϥϚʔ
    !
    !
    !
    8BOUFEMZͰ͸ߴ͍2JJUBྗ͕ٻΊΒΕΔ

    SwiftͰ̎Ґ

    View Slide

  3. ɾSwiftͷΞϓϦ։ൃͰϋϚͬͨ

    ɹ͜ͱ ̍̌ݸ

    !
    ɾXcode6ͱSwiftͷΞϓϦ։ൃͰ

    ɹ౿Μͩ஍ཕͨͪ̔ݸ
    ΞδΣϯμ

    View Slide

  4. Xcode6Ͱ৽نͷΞϓϦΛ։ൃͨ࣌͠ʹؾ͍ͮͨ͜ͱ
    Λ·ͱΊ·͢ɻΞϓϦͷ࢓༷͸ҎԼͷͱ͓Γɻ

    !
    - ։ൃݴޠ͸Swift

    - CocoapodsͰطଘObjcͷϥΠϒϥϦΛར༻

    - σϓϩΠλʔήοτ͸iOS8Ҏ্

    - StoryboardΛར༻

    - AutolayoutͱSizeClassesΛར༻

    View Slide

  5. ։ൃ؀ڥ͸ҎԼͷͱ͓Γɻ

    !
    - Xcode6͸Beta2, 3Λར༻

    - ݕূ࣮ػ͸iOS8 Beta2, 3ΛΠϯετʔϧͷiPhone5

    !
    Beta2Ͱ։ൃ͍ͯͨ͠ΒɺBeta3͕ग़·ͨ͠ ʘ(^o^)ʗ

    View Slide

  6. SwiftͷΞϓϦ։ൃͰ
    ϋϚͬͨ͜ͱ

    View Slide

  7. ҎԼͷ༷ͳObjCϝιουʹSwiftͷ
    ΫϩʔδϟΛ౉͢ํ๏
    @interface HogeFuga : NSObject
    + (void) hogeUsingBlock:(id)bock;
    @end

    View Slide

  8. ObjC id = Swift AnyObject

    View Slide

  9. HogeFuga.hogeUsingBlock( { () -> () in
    println("Fuga")
    })
    ERROR Type '() -> ()' does not
    conform to protocol 'AnyObject'

    View Slide

  10. var closures: AnyObject = { () in
    println("Fuga")
    }
    ERROR Type '() -> ()' does not
    conform to protocol 'AnyObject'

    View Slide

  11. typedef void (^Block)();
    !
    @interface HogeFuga (Wrapper)
    + (void) hogeUsingBlockWrapper:(Block)block;
    @end
    !
    @implementation HogeFuga (Wrapper)
    + (void) hogeUsingBlockWrapper:(Block)block;
    {
    [HogeFuga hogeUsingBlock:block];
    }
    @end
    ObjCͰܕΛ໌ࣔͨ͠ϒϩοΫΛ

    ࣋ͭϝιουͰϥοϓ͢Δ

    View Slide

  12. NSObject#descriptionΛΦʔόʔϥ
    Πυ͢Δ

    View Slide

  13. class Hoge: NSObject {
    var name: String?
    var note: String?
    override func description() -> String {
    return "Name = \(self.name),
    Note = \(self.note)"
    }
    }
    ERROR Method does not override
    any method from its superclass

    View Slide

  14. class Hoge: NSObject {
    var name: String?
    var note: String?
    override var description: String! {
    get {
    return "Name = \(self.name),
    Note = \(self.note)"
    }
    }
    }
    ϓϩύςΟͷΦʔόʔϥΠυ͢Δ

    View Slide

  15. ObjCͷenum஋ΛSwiftه๏Ͱهࡌ
    ͢Δํ๏͕Θ͔Βͳ͍

    View Slide

  16. Swift
    UIViewAutoresizing.FlexibleLeftMargin
    typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {
    UIViewAutoresizingNone = 0,
    UIViewAutoresizingFlexibleLeftMargin = 1 << 0,

    }
    ObjC
    UIViewAutoresizingFlexibleLeftMargin
    Θ͔Γ΍͍͢ྫ

    View Slide

  17. Swift
    UIViewAnimationOptions.LayoutSubviews
    typedef NS_OPTIONS(NSUInteger, UIViewAnimationOptions) {
    UIViewAnimationOptionLayoutSubviews = 1 << 0,
    UIViewAnimationOptionAllowUserInteraction = 1 << 1,

    }
    ObjC
    UIViewAnimationOptionLayoutSubviews
    ڐ༰ൣғͳྫ

    View Slide

  18. Swift
    HogeStyle.FugaValue1
    typedef NS_ENUM(NSInteger, HogeStyle) {
    HogeFugaDefault,
    HogeFugaValue1,
    HogeFugaValue2,
    HogeFugaSubtitle
    };
    ObjC
    HogeFugaValue1
    ෳࡶͳྫʢPrefix͕Ұக͍ͯ͠ͳ͍ʣ

    View Slide

  19. enumܕͷϝιουҾ਺΍ม਺ʹ
    enumͰఆٛ͞Εͨఆ਺Ҏ֎Λઃఆ
    ͢ΔͱΤϥʔʹͳΔ

    View Slide

  20. typedef NS_ENUM(NSInteger, UIViewContentMode) {
    UIViewContentModeScaleToFill,
    ...
    }
    !
    self.view.contentMode = 0
    !
    // => ERROR Cannot convert the expression's type
    '()' to type 'UIViewContentMode'
    Swiftͷܕ͸ݫ͍͠Ͱ͢Ͷ

    View Slide

  21. εΧϥʔܕͷΩϟετ͸ίϯόʔ
    δϣϯΛ࢖͏

    View Slide

  22. let i: Int = Int(1.0)
    let n: NSInteger = NSInteger(1.0)
    !
    let f: Float = Float(100)
    let d: Double = Double(100)
    let g: CGFloat = CGFloat(100)
    SwiftͰ͸εΧϥʔܕͷΩϟετ͸ͳ͍

    ୅ΘΓʹίϯόʔδϣϯΛར༻

    View Slide

  23. let index: NSInteger = 1
    let width: CGFloat = 100
    let r = width * (CGFloat)index
    !
    // => ERROR Consecutive statements on
    a line must be separated by ';'
    ObjCϥΠΫͳΩϟετ͸Ͱ͖ͳ͍

    View Slide

  24. let someObjects: [AnyObject] = [
    Movie(name: "2001: A Space", director: "Stan"),
    Movie(name: "Moon", director: "Duncan Jones"),
    Movie(name: "Alien", director: "Ridley Scott")
    ]
    !
    for object in someObjects {
    let movie = object as Movie // Type Casting !
    println("Movie: '\(movie.name)',
    dir. \(movie.director)")
    }
    ิ଍

    ΦϒδΣΫτܕ͸ΩϟετՄೳ

    View Slide

  25. for movie in someObjects as [Movie] {
    println("Movie: '\(movie.name)',
    dir. \(movie.director)")
    }
    ഑ྻΛΩϟετ͢ΔͱίϯύΫτʹॻ͚Δ

    View Slide

  26. CGFloatͱFloat·ͨ͸Doubleͷԋࢉ

    View Slide

  27. import CoreGraphics
    !
    typealias CGFloat = Float
    CoreGraphicsʹ͸CGFloat͸FloatͱΤΠϦΞ
    ε͞Ε͍ͯΔ

    View Slide

  28. let index: NSInteger = 1
    let width: CGFloat = 100
    let r1 = width * Float(index)
    !
    // => ERROR Could not find an overload
    for '*' that accepts the supplied
    arguments
    CGFloatͱFloatͷԋࢉ

    Ұݟਖ਼͘͠ಈ࡞ͦ͠͏͕ͩΤϥʔʹͳΔ

    View Slide

  29. ͳͥͳΒ

    iPhone5s(arm64)ΛλʔήοτʹϏ
    ϧυ͍ͯ͠Δ͔Β

    View Slide

  30. ͜ͷͱ͖CGFloat͸SwiftͷDouble
    ʹΤΠϦΞε͞ΕΔ

    View Slide

  31. let index: NSInteger = 1
    let width: CGFloat = 100
    let r2 = width * Double(index)
    // => OK
    iPhone5s(arm64)ͷ৔߹͸Doubleͩͱίϯ
    ύΠϧͰ͖Δ

    View Slide

  32. let index: NSInteger = 1
    let width: CGFloat = 100
    let r = width * CGFloat(index)
    // => OK
    CGFloatͱͷԋࢉ͸CGFloatʹίϯόʔ
    δϣϯ͠·͠ΐ͏

    View Slide

  33. ObjCͷNSIntegerͱSwiftͷIntͷԋ


    View Slide

  34. typealias NSInteger = Int
    !
    !
    let i: Int = 1
    let n: NSInteger = 1
    let x: CGFloat = 3
    let y: Float = 3
    let w = i + Int(x) + Int(y) // => OK
    let q = n + Int(x) + Int(y) // => OK
    !
    if n == i {
    println("HERE!") // => OK
    }

    View Slide

  35. let u: NSUInteger = 1
    !
    // ERROR => Use of undeclared type
    'NSUInteger'; did you mean to use
    'Int'?
    NSUInteger ͸ར༻Ͱ͖·ͤΜ

    View Slide

  36. ΫϩʔδϟܕϓϩύςΟͷΦϓ
    γϣφϧͳॻ͖ํ

    View Slide

  37. class Fuga {
    var completion: ( () -> () )?
    }
    ؙׅހͰׅΓ·͢

    View Slide

  38. ObjCͷClassܕΛύϥϝʔλʹͱΔ
    ϝιουʹSwiftͷClassΛ౉͢ํ๏

    View Slide

  39. @interface RKObjectMapping : RKMapping {
    +(instancetype)mappingForClass:(Class)objectClass
    }
    !
    !
    @implementation RKObjectMappingOp…
    {
    return [mapping.objectClass new];
    }
    ౉ͨ͠Classܕ͕ObjCଆͰnew͞ΕΔέʔε

    ʢྫɿ Restkit)

    View Slide

  40. Swift͔ΒͲ͏͍͏ clazz Λ౉ͤ͹͍͍ͷ͔
    class HogeModel: NSObject {
    }
    !
    !
    var clazz = ???

    let mapping: RKObjectMapping =
    RKObjectMapping(forClass: clazz)

    View Slide

  41. var clazz: AnyClass =
    NSClassFromString(“WTDHogeModel”)
    !
    // ERROR => EXC_BAD_INSTRUNCTION
    ࣦഊᶃ

    NSClassFromStringͰ౉͢

    View Slide

  42. var clazz: AnyClass =
    object_getClass(WTDHogeModel())
    !
    !
    // newͰERROR
    [mapping.objectClass new];
    ࣦഊᶄ

    object_getClassͰ౉͢

    View Slide

  43. var clazz: NSObject.Type = WTDHogeModel.self

    let mapping: RKObjectMapping =
    RKObjectMapping(forClass: clazz)
    !
    !
    // ʹʼ OK
    ݁࿦

    NSObject.TypeΛ౉͢

    View Slide

  44. γϯάϧτϯύλʔϯΛ࣮૷͢Δ
    ̏ͭͷํ๏

    View Slide

  45. !
    !
    ஗ԆॳظԽʢlazy initializationʣͱεϨου
    ηʔϑʢthread safetyʣ͕ߟྀ͞Ε࣮ͨ૷

    View Slide

  46. class Singleton {
    class var sharedInstance : Singleton {
    struct Static {
    static var onceToken : dispatch_once_t = 0
    static var instance : Singleton? = nil
    }
    dispatch_once(&Static.onceToken) {
    Static.instance = Singleton()
    }
    return Static.instance!
    }
    }
    dispatch_onceͰఆٛ
    ObjCͱಉ༷ͷ࣮૷ํ๏

    ຖճ͜ΕΛॻ͘ʹͷ͸େม

    View Slide

  47. let _SingletonSharedInstance = Singleton()
    !
    class Singleton {
    class var sharedInstance : Singleton {
    return _SingletonSharedInstance
    }
    }
    άϩʔόϧఆ਺Ͱఆٛ
    ࠓޙSwiftͷݴޠ࢓༷͕มߋ͞Εہॴతά
    ϩʔόϧม਺͕ఆٛͰ͖ΔΑ͏ʹͳΕ͹ɺ
    ͜ͷ࣮૷ํ๏͕΋ͬͱ΋γϯϓϧ

    View Slide

  48. class Singleton {
    class var sharedInstance : Singleton {
    struct Static {
    static let instance : Singleton = Singleton()
    }
    return Static.instance
    }
    }
    structͷstaticఆ਺Ͱఆٛ ʢਪ঑ʣ
    Swiftͷclass͸staticఆ਺Λར༻Ͱ͖ͳ͍ͷ
    ͰɺstructͰωετͯ͠staticఆ਺Λอ࣋

    View Slide

  49. Xcode6ͱSwift&iOS8
    ͷΞϓϦ։ൃͰ౿Μ
    ͩ஍ཕͨͪ

    View Slide

  50. ίϯύΠϧΤϥʔ

    XXXHeaderϑΝΠϧ has been
    modified since the precompiled header

    View Slide

  51. fatal error: file ‘…/UIKit.framework/
    Headers /UIVisualEffectView.h’ has
    been modified since the precompiled
    header …

    View Slide

  52. ରԠํ๏

    ຖճͳ͔ͥͳ͓ΔରԠํ๏͕·ͪ·ͪ

    !
    - Xcode6࠶ىಈ

    - ϏϧυΛΫϦʔϯ͢Δ

    - DerivedDataΛ࡟আ͢Δ

    - OSXΛ࠶ىಈ͢Δ

    - Xcode6ΛೖΕͳ͓͢ orz

    View Slide


  53. IBOutletͷStoryboardͱͷίωΫ
    γϣϯ͋Γ͕දࣔ͞Εͳ͍৔߹͕
    ͋Δ

    View Slide

  54. ίϯύΠϧޙͷΞϓϦͷڍಈ͸ਖ਼͘͠઀ଓ
    ͞Ε͍ͯΔঢ়ଶͰಈ࡞͍ͯ͠·ͨ͠

    View Slide


  55. StoryboardͷϑΝΠϧΛ։͍ͯ΋
    XMLͰදࣔ͞ΕΔ

    View Slide

  56. XML…

    View Slide

  57. ໌ࣔతʹ։͖·͠ΐ͏

    View Slide


  58. ιʔείʔυϋΠϥΠτͱೖྗิ
    ׬͕ޮ͔ͳ͘ͳΔ

    View Slide

  59. ͨ·ʹ෮׆΋͠·͆͢

    View Slide


  60. γϛϡϨʔλʔͰΞϓϦΛىಈ͠
    Α͏ͱ͢ΔͱΤϥʔʹͳΔ

    View Slide

  61. Xcode6ͱγϛϡϨʔλʔΛ࠶ىಈ
    ͨ͠Βͳ͓Γ·ͨ͠ɻ

    View Slide


  62. Xcode5ͱXcode6ͷγϛϡϨʔλʔ
    Ͱಉ࣌ʹΞϓϦΛىಈͰ͖ͳ͍

    View Slide

  63. ͲͪΒ͔ͷγϛϡϨʔλʔΛऴྃ
    ͠·͠ΐ͏

    View Slide


  64. switchͱॻ͘ͱXcode͕ϑϦʔζ͢
    Δ

    View Slide

  65. Beta3Ͱ͸·ͩग़͍ͯͳ͍Ͱ͢

    View Slide


  66. ޡͬͯϓϩδΣΫτΛXcode5Ͱ։
    ͍ͯStroyboardΛ։͘ͱXcode6Ͱ
    Stroyboard͕͓͔͘͠ͳ͍ͬͯΔ

    View Slide

  67. Xcode5Ͱޡͬͯ։͍ͨΒԿ΍ΒΤϥʔ͕
    ϑΝΠϧ͕ഁյ͞Ε·ͨ͠ɻ

    git reset ͳͲͰϑΝΠϧΛ໭͠·͠ΐ͏ɻ

    View Slide

  68. Finder͔ΒϓϩδΣΫτϑΝΠϧΛ
    μϒϧΫϦοΫͯ͠։͘ͱXcode5
    Ͱ։͔ΕΔ͜ͱ΋͋Γ·͢ɻ

    View Slide

  69. Xcode5Λىಈ͢ΔͱɺXcode6Ͱ࡞
    ۀ͍ͯͨ͠ϓϩδΣΫτΛউखʹ
    ։͘৔߹͕͋Γ·͢ɻ

    View Slide

  70. ༧๷ࡦ

    !
    ̍. gitͳͲͰࡉ͔͘ίϛοτͯ͠ϩʔϧόοΫͰ͖Δ
    Α͏ʹ

    !
    ̎. Xcode6ͰϓϩδΣΫτΛ։͍ͨΒετʔϦϘʔυ
    Λ࠷ऴฤूը໘ʹͯ͠ด͡ͳ͍

    !
    ̏. Xcode6Λऴྃ͢Δͱ͖͸ϓϩδΣΫτΛด͔ͯ͡
    Βऴྃ͢Δ

    !
    ̐. Xcode5ΛࣺͯΔ͆

    View Slide

  71. iOS,Android
    Rails ΤϯδχΞ
    ืूத
    [email protected]
    ڵຯ͕͋Δํ͸ͪ͜Β͔Β͝࿈བྷ͍ͩ͘͞
    ৽͍ٕ͠ज़ʹͲΜͲΜ௅ઓ͍ͨ͠
    ϞόΠϧΤϯδχΞɾ΢Υϯςουʂʂ
    ͪ͜Β͔ΒͰ΋OKͰ͢

    View Slide

  72. ͓ΘΓ

    View Slide