Slide 1

Slide 1 text

͸ͯͳͷ iOSΞϓϦͱSwift @Hatena Engineer Seminar #4

Slide 2

Slide 2 text

id:yashigani_w @yashigani • http://yashigani.hatenablog.com • 2014/7ೖࣾ • ΞϓϦέʔγϣϯΤϯδχΞ • iOS/Android ࣌ʑ Perl

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

͸ͯͳͰͷࣄྫ

Slide 5

Slide 5 text

͸ͯͳϒοΫϚʔΫShare Extension • ΄΅શͯSwiftͰ࣮૷ • Swiftͷ࣮ݧϓϩδΣΫτͱ͍ ͏Ґஔ͚ͮ

Slide 6

Slide 6 text

ͳͥShare ExtensionͰࢼ͔ͨ͠ • App Extension͸ΞϓϦʹ΋͏Ұͭখ͍͞ΞϓϦΛ όϯυϧ͢Δܗଶ • ΞϓϦͷن໛ͱͯ͠খ͘͞ɼࣦഊͯ͠΋վमָ͕ • SwiftΛࢼ͢ϓϩδΣΫτʹ࠷ద

Slide 7

Slide 7 text

݁Ռ • ࠓޙͷϓϩδΣΫτͰ͸ඪ४తʹSwiftΛ࠾༻͢Δ ͜ͱʹܾఆ • طʹࣾ಺޲͚ϥΠϒϥϦͷ͍͔ͭ͘͸SwiftʹҠߦ • Objective-Cॻ͖͍ͨͬͯਓ͸͍ͳ͘ͳͬͨ

Slide 8

Slide 8 text

ͳͥɼ͋͑ͯखʹೃછΜͩ Objective-CΛغͯSwiftΛ࠾༻͢Δͷ͔

Slide 9

Slide 9 text

- (Bookmark *)latestHotEntry:(NSArray *)bookmarks { NSPredicate *predicate = [NSPredicate predicateWithBlock:^(Bookmark *b, NSDictionary *bindings) { return b.isHotentry; }]; NSArray *hotentries = [bookmarks filteredArrayUsingPredicate:predicate]; NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:@"bookmarked" ascending:NO]; NSArray *sortedHotentries = [hotentries sortedArrayUsingDescriptors:@[descriptor]]; return sortedHotentries.firstObject; }

Slide 10

Slide 10 text

func latestHotentry(bookmarks bs: [Bookmark]) -> Bookmark? { return bs.filter { $0.isHotentry } .sorted { (b1: Bookmark, b2: Bookmark) in b1.bookmarked.compare(b2.bookmarked) == .OrderedDescending }.first }

Slide 11

Slide 11 text

Generics • ΑΓ҆શʹίʔυΛॻ͘͜ͱ͕Ͱ͖Δ • Objective-CͰ๷ޚతͳίʔυΛॻ͘ͱ৑௕ • (࣍ཉ͔ͬͨ͠ͷ͸ܕΞϊςʔγϣϯ) • ΑΓॊೈͳίʔυ͕ॻ͚Δ

Slide 12

Slide 12 text

- (Bookmark *)latestHotEntry:(NSArray *)bookmarks { for (id obj in bookmarks) { if (![obj isKindOfClass:Bookmark.class]) { return nil; } } NSPredicate *predicate = [NSPredicate predicateWithBlock:^(Bookmark *b, NSDictionary *bindings) { return b.isHotentry; }]; NSArray *hotentries = [bookmarks filteredArrayUsingPredicate:predicate]; NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:@"bookmarked" ascending:NO]; NSArray *sortedHotentries = [hotentries sortedArrayUsingDescriptors:@[descriptor]]; return sortedHotentries.firstObject; }

Slide 13

Slide 13 text

Functional Programming • map, filter, sort etc. • ෳࡶͳ͜ͱΛ׬݁ʹදݱͰ͖Δ • ैདྷ͸ख࡞Γײ͕͋ͬͨ • NSPredicate, NSSortDescriptor

Slide 14

Slide 14 text

Closures • Objective-CͷΤϯδχΞ͸ΈΜͳBlocks͍͖ͩ͢ • (׳ΕΕ͹)ಡΊΔ • (׳Εͯ΋)ͦΒͰ͸ॻ͚ͳ͍ • ແ͔ͬͨ࣌୅ʹ૝͍Λ஘ͤͳ͕Β͋Γ͕ͨ͘࢖͏

Slide 15

Slide 15 text

int (^add)(int, int) = ^(int x, int y) { return x + y; }; add(1, 2); @interface Hoge : NSObject @property (copy) int (^block)(int, int); @property (copy) NSString *title; - (void)fuga:(int(^)(int, int))block; @end Objective-C

Slide 16

Slide 16 text

fuckingblocksyntax.com

Slide 17

Slide 17 text

Swift let add = { (x: Int, y: Int) -> Int in return x + y } add(1, 2) class Hoge: NSObject { var closure: (Int, Int) -> Int var title: String func fuga(closure: (Int, Int) -> Int) { // ... } }

Slide 18

Slide 18 text

΄͔ʹ΋ • Tuples • Optional • Playground(REPL) • namespace(classͷதʹclass/enum/struct͕ॻ͚Δ)

Slide 19

Slide 19 text

Objective-C͔ΒSwift΁ • ΑΓݫີͳ੩తܕ෇͚ • ख࡞Γ͔Βݴޠαϙʔτ΁ • Cͱͷޓ׵ΛغͯΔ͜ͱʹΑͬͯಘͨϞμϯͳػೳ

Slide 20

Slide 20 text

͍͚ͯͳ͍ͱ͜Ζ΋͋Δ • աڈͷࢿ࢈Λͦͷ··࢖͑ͳ͍͜ͱ͕͋Δ • CͰॻ͔Εͨ΋ͷͷҰ෦(ex: CommonCrypto) • C++Ͱॻ͔Εͨ΋ͷ • ࠷దԽͰҊ֎յΕΔ • ։ൃπʔϧ

Slide 21

Slide 21 text

࠷దԽͰյΕΔྫ(1) var query: [String: AnyObject] = makeKeychainQuery(account: account, type: type) var status: OSStatus = errSecSuccess var result: AnyObject? status = withUnsafeMutablePointer(&result, { SecItemCopyMatching(query, UnsafeMutablePointer($0)) }) query[kSecValueData] = passwordData

Slide 22

Slide 22 text

࠷దԽͰյΕΔྫ(2) var query: [String: AnyObject] = makeKeychainQuery(account: account, type: type) var status: OSStatus = errSecSuccess var result: AnyObject? status = withUnsafeMutablePointer(&result, { SecItemCopyMatching(query, UnsafeMutablePointer($0)) }) query[kSecValueData] = passwordData ࠷దԽ༗ޮ࣌ɼͳ͔ͥ։์͞Εͯ͠·͍ ͦͷޙΞΫηε͢ΔͱΫϥογϡ͢Δ

Slide 23

Slide 23 text

࠷దԽͰյΕΔྫ(3) var query: [String: AnyObject] = makeKeychainQuery(account: account, type: type) var status: OSStatus = errSecSuccess var result: AnyObject? let temp = query status = withUnsafeMutablePointer(&result, { SecItemCopyMatching(temp, UnsafeMutablePointer($0)) }) query[kSecValueData] = passwordData յΕͯ΋͍͍Α͏ʹҰ࣌ม਺ʹୀආ͢ΔͱճආͰ͖Δ

Slide 24

Slide 24 text

࠷దԽ஫ҙϙΠϯτ • TestFlightͳͲͰϕʔλΛ഑෍ͨ͠ͱ͖ʹॳΊͯ
 ؾ͕ͭ͘͜ͱ͕ଟ͍ • σϑΥϧτͰ͸σόοά࣌ʹ࠷దԽΛ͠ͳ͍ • Ͳ͏ߟ͑ͯ΋͓͔͍͠ͱ͜ΖͰΫϥογϡͯͨ͠Β ेதീ۝࠷దԽͰյΕ͍ͯΔ • ߄ͯͳ͍Α͏ʹϦϦʔεʹ༨༟Λ࣋ͬͨQAܭը

Slide 25

Slide 25 text

ϋϚͬͨͱ͖ͷΞυόΠε • σόοά࣮ߦͰ΋࠷దԽϨϕϧΛ্͛Ε͹࠶ݱՄೳ • Ұ࣌ม਺Λ࢖͏(ࠓճͷྫͷΑ͏ͳ৔߹) • Swift෼Λഉআ͢Δ(structΛ࢖Θͳ͍ɼNSObjectΛ ܧঝ͢Δ) • ࠶ݱ͸؆୯ͳͷͰɼఘΊͳ͍ڧ͍৺Λ࣋ͭ

Slide 26

Slide 26 text

։ൃπʔϧ͕μϝ • IDEͷػೳ͕΄΅࢖͑ͳ͍ • ΍ͨΒΫϥογϡ͢ΔγϯλοΫεϋΠϥΠτ+ ίʔυิ׬ • ϦϑΝΫλϦϯάػೳ͸ະαϙʔτ • શ͘ಈ͔ͳ͍Θ͚Ͱ͸ͳ͍ͷͰզຫ͢Ε͹࢖͑Δ

Slide 27

Slide 27 text

΄͔ʹ΋ • ܕਪ࿦͕͓΋ͬͨΑΓϔϘ͍ • ϦϑϨΫγϣϯ͕·ͩແ͍ • Objective-C͸ٯʹ͜Ε͕ΊͬͪΌڧ͔ͬͨ

Slide 28

Slide 28 text

SwiftͰiOSΞϓϦΛ ࡞ΔΦεεϝߏ੒

Slide 29

Slide 29 text

CocoaPods vs Carthage • CocoaPods͸0.36(preview൛)ΑΓSwiftʹରԠ • Carthage͸࠷ۙग़͖ͯͨ΍ͭ • iOS 8͔Β࢖͑Δɼdynamic frameworkΛϏϧυ͠ projectʹຒΊΔ • աڈͷࢿ࢈͕࢖͑Δ͜ͱ΍ɼiOS 7ͷαϙʔτ΋ߟ͑Δ ͱ·ͩࠓ͸CocoaPodsΛ࢖͏ͷ͕ແ೉

Slide 30

Slide 30 text

Alamofire vs AFNetworking • ඒ͍͠SwiftͷੈքͰด͍ͯ͡Δͷ͕Alamofire • ࡉ͔͍͜ͱ(ಛʹmultipartͰ௨৴)͕͍ͨ͠৔߹͸
 ໎ΘͣAFNetworking

Slide 31

Slide 31 text

JSON • Optionalͱͱʹ͔͘૬ੑ͕ѱ͍ • ૉ๿ʹ΍ΔͱΊͪΌͪ͘Όωετ͕ਂ͘ͳΔ • swift-json΍SwiftyJSONΛ࢖͏͜ͱ΋ݕ౼Ͱ͖Δ ͕ɼMantleΛ࢖͏ͷ͕Φεεϝ

Slide 32

Slide 32 text

ૉ๿ʹ΍Δͱ͜͏ͳΔ let jsonObject : AnyObject! = NSJSONSerialization.JSONObjectWithData(dataFromTwitter, options: NSJSONReadingOptions.MutableContainers, error: nil) if let statusesArray = jsonObject as? NSArray { if let aStatus = statusesArray[0] as? NSDictionary { if let user = aStatus["user"] as? NSDictionary { if let userName = user["name"] as? NSString { //Finally We Got The Name } } } }

Slide 33

Slide 33 text

MantleͳΒ͜͏ let entries = MTLJSONAdapter.modelsOfClass(BookmarkEntry.self, fromJSONArray: JSONEntries, error: nil) return entries as [BookmarkEntry]

Slide 34

Slide 34 text

͸ͯͳͷ ϞόΠϧΞϓϦΤϯδχΞ

Slide 35

Slide 35 text

εϚʔτձ • ٕज़ڞ༗/εΩϧΞοϓ + ϞόΠϧΞϓϦ։ൃ؀ڥ ੔උɼ޲্Λ໨తͱͨ͠νʔϜԣஅ૊৫ • ٕज़ڞ༗͸ඇৗʹ׆ൃ • ։ൃ؀ڥʹ͍ͭͯ͸େ͖ͳݖݶ͕༩͑ΒΕ͍ͯΔͷ Ͱ΍Δؾ͍ͩ͠Ͱ΍Γ͍ͨΑ͏ʹͰ͖Δ

Slide 36

Slide 36 text

͋Γ͕ͱ͏͍͟͝·ͨ͠