Slide 1

Slide 1 text

1VTI-PDBM /PUJpDBUJPO ͱͦͷपล 2014/2/23 ঙ࢘ ܒี

Slide 2

Slide 2 text

ࣗݾ঺հ • ঙ࢘ ܒี • twitter/github: WorldDownTown • iOSྺ1೥ iQONͷiOSΤϯδχΞ

Slide 3

Slide 3 text

J20/

Slide 4

Slide 4 text

J20/ ϑΝογϣϯࡶࢽΛݟΔΑ͏ʹτϨϯυ͕Θ͔ͬͯɺ ݟ͍ͯΔ΋ͷ͕௨ൢͰ͖ΔແྉͷϑΝογϣϯ ίʔσΟωʔτΞϓϦ AppStoreͷ2012೥ϕετΞϓϦʹબग़ʂ

Slide 5

Slide 5 text

໨࣍ • Push / Local Notification ͱ͸ʁ • Push Notification • Local Notification • Push / Local Notificationൺֱ • iOS7ͷػೳ • ·ͱΊ

Slide 6

Slide 6 text

Push / Local Notification ࢖ͬͯ·͔͢ʁ

Slide 7

Slide 7 text

Push / Local Notification ͱ͸ʁ

Slide 8

Slide 8 text

Push / Local Notification ͱ͸ʁ ϩʔΧϧ௨஌͓Αͼϓογϡ௨஌͕ղܾ͢Δ໰୊ ϑΥΞάϥ΢ϯυͰ͸ɺ౓ʹͭͷΞϓϦέʔγϣϯ͔͠ΞΫςΟϒʹͳΕ·ͤΜɻ ଟ͘ͷΞϓϦέʔγϣϯ͸ɺ࣌ؒϕʔε·ͨ͸૬ޓ઀ଓ͞Εͨ؀ڥͰಈ࡞͍ͯ͠Δͨ ΊɺΞϓϦέʔγϣϯ͕ϑΥΞάϥ΢ϯυʹͳ͍ͱ͖ʹɺϢʔβ͕ؔ৺Λ͍࣋ͬͯΔ Πϕϯτ͕ൃੜ͢ΔՄೳੑ͕͋Γ·͢ɻ ϩʔΧϧ௨஌͓Αͼϓογϡ௨஌ʹΑΓɺΞϓϦέʔγϣϯ͸ɺ͜ΕΒͷΠϕϯτ͕ ൃੜͨ͜͠ͱΛϢʔβʹ௨஌Ͱ͖ΔΑ͏ʹͳΓ·͢ɻ ʰ-PDBM͓Αͼ1VTI/PUJpDBUJPOϓϩάϥϛϯάΨΠυʱ

Slide 9

Slide 9 text

Push / Local Notification ͱ͸ʁ ϩʔΧϧ௨஌͓Αͼϓογϡ௨஌͕ղܾ͢Δ໰୊ ϑΥΞάϥ΢ϯυͰ͸ɺ౓ʹͭͷΞϓϦέʔγϣϯ͔͠ΞΫςΟϒʹͳΕ·ͤΜɻ ଟ͘ͷΞϓϦέʔγϣϯ͸ɺ࣌ؒϕʔε·ͨ͸૬ޓ઀ଓ͞Εͨ؀ڥͰಈ࡞͍ͯ͠Δͨ ΊɺΞϓϦέʔγϣϯ͕ϑΥΞάϥ΢ϯυʹͳ͍ͱ͖ʹɺϢʔβ͕ؔ৺Λ͍࣋ͬͯΔ Πϕϯτ͕ൃੜ͢ΔՄೳੑ͕͋Γ·͢ɻ ϩʔΧϧ௨஌͓Αͼϓογϡ௨஌ʹΑΓɺΞϓϦέʔγϣϯ͸ɺ͜ΕΒͷΠϕϯτ͕ ൃੜͨ͜͠ͱΛϢʔβʹ௨஌Ͱ͖ΔΑ͏ʹͳΓ·͢ɻ ʰ-PDBM͓Αͼ1VTI/PUJpDBUJPOϓϩάϥϛϯάΨΠυʱ ར༻཰޲্ʹͭͳ͕Δ

Slide 10

Slide 10 text

Push / Local Notification ͱ͸ʁ ● ܯࠂ΍όφʔ͕දࣔ͞ΕΔ ● ΞϓϦέʔγϣϯΞΠίϯʹόοδ͕ͭ͘ ● α΢ϯυ͕໐Δ Ϣʔβʔʹͱͬͯ͸ Push Notification΋Local Notification΋ ಉ͡෺ʹݟ͑Δ

Slide 11

Slide 11 text

Push / Local Notification ͱ͸ʁ ● ࣮૷ํ๏ͷҧ͍ ● ϝϦοτ/σϝϦοτͷҧ͍ ΞϓϦέʔγϣϯʹͱͬͯ͸ Push NotificationͱLocal Notification͸ ҧ͏෺ʹݟ͑Δ

Slide 12

Slide 12 text

໨࣍ • Push / Local Notification ͱ͸ʁ • Push Notification • Local Notification • Push / Local Notificationൺֱ • iOS7ͷػೳ • ·ͱΊ

Slide 13

Slide 13 text

1VTI/PUJpDBUJPO

Slide 14

Slide 14 text

1VTI/PUJpDBUJPO • iPhone OS 3.0ʙ • αʔό͔ΒiOS୺຤΁௨஌ΛૹΔ • αʔό͔Β೚ҙͷϝοηʔδ/λΠϛϯά Ͱૹ৴Մೳ

Slide 15

Slide 15 text

1VTI/PUJpDBUJPOͷ࢓૊Έ  1. Apple Push Notification Service (APNs) ͱ͍͏ήʔτ΢ΣΠʹσόΠε Λొ࿥ 2. σόΠε͕APNs͔ΒdeviceTokenΛड͚औΔ 3. ΞϓϦ͕σόΠε͔ΒdeviceTokenΛड͚औΔ 4. deviceTokenΛϓϩόΠμ(ΞϓϦ ӡӦऀͷαʔό౳)ʹొ࿥͢Δ

Slide 16

Slide 16 text

1VTI/PUJpDBUJPOͷ࢓૊Έ  1. ϓϩόΠμ͸deviceTokenͱpayloadΛؚΉ௨஌ύοέʔδΛ࡞੒ ϦϞʔτ௨஌ͷσʔλ͸Ұํ޲ʹྲྀΕΔ 2. ϓϩόΠμ͸ͦͷ௨஌ΛAPNsʹૹ৴ 3. APNs͕ͦͷ௨஌ΛσόΠεʹ഑৴ʢϓογϡʣ

Slide 17

Slide 17 text

1VTI/PUJpDBUJPOΛૹΔ ४උ • ϓϩόΠμͷ؀ڥߏங • σόΠετʔΫϯઃఆॲཧ࣮૷

Slide 18

Slide 18 text

ϓϩόΠμͷ؀ڥߏங লུ

Slide 19

Slide 19 text

ϓϩόΠμͷ؀ڥߏங ໘౗ͳ؀ڥઃఆΛ͠ͳͯ͘΋͍͍Α͏ʹͳ͖ͬͯ·ͨ͠

Slide 20

Slide 20 text

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // APNsにデバイス登録 UIRemoteNotificationType notificationType = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert; [[UIApplication sharedApplication] registerForRemoteNotificationTypes:notificationType]; ! return YES; } - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { NSString *deviceTokenString = deviceToken.description; NSCharacterSet *characterSet = [NSCharacterSet characterSetWithCharactersInString:@"<>"]; deviceTokenString = [deviceTokenString stringByTrimmingCharactersInSet:characterSet]; deviceTokenString = [deviceTokenString stringByReplacingOccurrencesOfString:@" " withString:@""]; ! // deviceTokenStringをサーバに送信 } σόΠετʔΫϯ ઃఆॲཧ࣮૷ UIApplicationDelegateͷԼهͷϝιουΛ࣮૷

Slide 21

Slide 21 text

͜ΕͰ४උ׬ྃ ϓϩόΠμ͔Β 1VTIૹ৴Մೳ

Slide 22

Slide 22 text

Ԡ༻ • payloadͷΧελϜϓϩύςΟ • σόΠετʔΫϯઃఆλΠϛϯά

Slide 23

Slide 23 text

QBZMPBEͷΧελϚΠζ { "aps":{ "alert":"hello", "badge":1, "sound":"default" } } γϯϓϧͳQBZMPBE

Slide 24

Slide 24 text

QBZMPBEͷΧελϚΠζ { "aps":{ "alert":{ "body":"hello", "action-loc-key":"ゲームを再開", "launch-image":"push.png" }, "badge":1, "sound":"default" } } BMFSUͷࢠϓϩύςΟͰΧελϚΠζͰ͖Δ

Slide 25

Slide 25 text

QBZMPBEͷΧελϚΠζ BMFSUͷࢠϓϩύςΟ Ωʔ ஋ͷܕ આ໌ CPEZ จࣈྻ 1VTI௨஌࣌ͷϝοηʔδ BDUJPOMPDLFZ จࣈྻ 1VTIىಈϘλϯͷϝοηʔδ MPDLFZ จࣈྻ 1VTI௨஌࣌ͷϩʔΧϥΠζϝοηʔδ -PDBMJ[BCMFTUSJOHTϑΝΠϧ಺ͷΩʔΛ༩͑Δ MPDBSHT จࣈྻͷ഑ྻ MPDLFZ಺ͷॻࣜࢦఆࢠͷ୅ΘΓʹ දࣔ͢Δม਺จࣈྻ஋ MBVODIJNBHF จࣈྻ 1VTI͔Βͷىಈ࣌ʹදࣔ͞ΕΔը૾ͷϑΝΠϧ໊ ࢦఆ͠ͳ͚Ε͹%FGBVMUQOH

Slide 26

Slide 26 text

QBZMPBEͷΧελϚΠζ BDUJPOMPDLFZ

Slide 27

Slide 27 text

QBZMPBEͷΧελϚΠζ { "aps":{ "alert":"hello", "badge":1, "sound":"default" }, "key":"value" } ΞϓϦέʔγϣϯʹLFZWBMVFΛ౉͢͜ͱ͕Ͱ͖Δ Push௨஌ىಈͷϩάΛམͱͨ͠Γ! ىಈ࣌ͷViewControllerΛࢦఆͨ͠ΓͰ͖Δ

Slide 28

Slide 28 text

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSMutableDictionary *payload = [launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey] mutableCopy]; payload[@"type"] = @"not_running"; if (payload) { // アプリの未起動時にプッシュ通知を受け取り、ユーザーがアクションボタンをタップしたとき // payload[@"key"] -> value [self startWithPayload:payload]; } return YES; } - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { NSMutableDictionary *payload = userInfo.mutableCopy; if (application.applicationState == UIApplicationStateActive) { // フォアグラウンドでプッシュ通知を受け取ったとき payload[@"type"] = @"active"; } else { // アプリがサスペンド中にプッシュ通知を受け取り、ユーザーがアクションボタンをタップしたとき payload[@"type"] = @"background"; } // payload[@"key"] -> value [self startWithPayload:payload]; } UIApplicationDelegateͷԼهͷϝιουΛ࣮૷ QBZMPBEͷΧελϚΠζ

Slide 29

Slide 29 text

σόΠετʔΫϯઃఆͷ λΠϛϯά - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // APNsにデバイス登録 UIRemoteNotificationType notificationType = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert; [[UIApplication sharedApplication] registerForRemoteNotificationTypes:notificationType]; ! return YES; } Α͘ݟΔαϯϓϧ

Slide 30

Slide 30 text

σόΠετʔΫϯઃఆͷ λΠϛϯά ·ͩͲΜͳΞϓϦ͔Α͘Θ͔Βͳ͍ͷʹɺ! ॳճىಈͷλΠϛϯάͰϓογϡͷڐՄ! Λฉ͍ͯ͠·͏ͱڐՄͯ͠΋Β͑ͳ͍…

Slide 31

Slide 31 text

σόΠετʔΫϯઃఆͷ λΠϛϯά νϡʔτϦΞϧʹ͋ΔΑ͏ʹ! application:didFinishLaunchingWithOptions: ಺Ͱ! registerForRemoteNotificationTypesΛίʔϧͤͣɺ! ϓογϡ௨஌Λड͚औΔϝϦοτड़΂ͨ͏͑Ͱ! ॳΊͯregisterForRemoteNotificationTypes:Λίʔϧ͢Δ iQONͰ΋PUSHઃఆ཰͕޲্!

Slide 32

Slide 32 text

໨࣍ • Push / Local Notification ͱ͸ʁ • Push Notification • Local Notification • Push / Local Notificationൺֱ • iOS7ͷػೳ • ·ͱΊ

Slide 33

Slide 33 text

-PDBM/PUJpDBUJPO • iOS 4.0ʙ • ໘౗ͳϓϩόΠμઃఆ͕ෆཁ • λΠϚʔ΍܁Γฦ͠Ͱ௨஌ΛදࣔͰ͖Δ • ΞϓϦ͕OSʹରͯ͠௨஌ͷεέδϡʔϧ ΍ςΩετΛઃఆ͢Δ

Slide 34

Slide 34 text

௨஌ઃఆ UILocalNotification *notification = [UILocalNotification new]; notification.alertBody = @"UILocalNotificationのテスト"; // アラートメッセージ notification.fireDate = [[NSDate date] dateByAddingTimeInterval:(60 * 3)]; // 3分後に通知 notification.applicationIconBadgeNumber = 1; // アプリアイコンのバッジ数 notification.timeZone = [NSTimeZone localTimeZone]; // タイムゾーン notification.alertAction = @"起動して!"; // 起動ボタンのテキスト notification.hasAction = NO; // YESならアラートからアプリを起動しない notification.soundName = UILocalNotificationDefaultSoundName; // 通知音 notification.alertLaunchImage = @"push.png"; // 起動時の画像指定しなければDefault.png notification.userInfo = @{@"id":@1234}; // カスタムプロパティ [[UIApplication sharedApplication] scheduleLocalNotification:notification]; // 通知の予約 Push Notificationʹൺ΂ͨΒྦ͕ग़Δ΄Ͳ؆୯! Push Notificationͱಉ͡Α͏ͳࡉ͔͍Φϓγϣϯ΋͋Δ

Slide 35

Slide 35 text

௨஌Ωϟϯηϧ NSArray *notifications = [UIApplication sharedApplication].scheduledLocalNotifications; for (UILocalNotification *notification in notifications) { if ([notification.userInfo[@"id"] integerValue] == 1234) { [[UIApplication sharedApplication] cancelLocalNotification:notification]; } } ΧϨϯμʔΞϓϦͰεέδϡʔϧΛ࡟আ࣌͠ͳͲɺ! ௨஌ΛΩϟϯηϧ͢Δ͜ͱ͕Ͱ͖Δ [[UIApplication sharedApplication] cancelAllLocalNotifications]; શͯͷ௨஌ΛΩϟϯηϧ ಛఆͷ௨஌ΛΩϟϯηϧ͢Δʹ͸userInfoͷ৘ใ͔ΒΩϟϯηϧ͢Δ௨஌Λಛఆ͢Δ

Slide 36

Slide 36 text

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { UILocalNotification *notification = launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]; if (notification) { // アプリの未起動時に通知を受け取り、ユーザーがアクションボタンをタップしたとき // notification.userInfo[@"key"] -> value [self startWithNotification:notification]; } return YES; } - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { if (application.applicationState == UIApplicationStateActive) { // フォアグラウンドで通知を受け取ったとき } else { // アプリがサスペンド中に通知を受け取り、ユーザーがアクションボタンをタップしたとき } // notification.userInfo[@"key"] -> value [self startWithNotification:notification]; } UIApplicationDelegateͷԼهͷϝιουΛ࣮૷ (Push Notificationͱ΄΅ಉ͡) ىಈ࣌ͷ੍ޚ

Slide 37

Slide 37 text

-PDBM/PUJpDBUJPOԠ༻ྫ Sleipnir͕νϡʔτϦΞϧͱͯ͠Local Notification! Λར༻͍ͯ͠Δ

Slide 38

Slide 38 text

-PDBM/PUJpDBUJPOԠ༻ྫ ࣮૷Λ૝૾ͯ͠Έͨ • AppDelegateͷapplicationWillResignActive:Ͱ௨஌ͷઃఆ • notification.soundName = nil; • νϡʔτϦΞϧͱͯ͠఻͍͑ͨػೳΛطʹ࢖ͬͨ͜ͱ͕ ͋Δ৔߹͸ɺ௨஌ΛΩϟϯηϧ

Slide 39

Slide 39 text

໨࣍ • Push / Local Notification ͱ͸ʁ • Push Notification • Local Notification • Push / Local Notificationൺֱ • iOS7ͷػೳ • ·ͱΊ

Slide 40

Slide 40 text

1VTI-PDBM/PUJpDBUJPOൺ ֱ 1VTI/PUJpDBUJPO -PDBM/PUJpDBUJPO ઃఆ؀ڥߏங ϓϩόΠμ؀ڥ΍ 1SPWJTJPOJOHͷઃఆ͕ ඞཁ ωΠςΟϒͷίʔυ ͷΈ ௨஌λΠϛϯά ϓϩόΠμଆ͔Β೚ ҙʹมߋՄೳ εέδϡʔϦϯά͕Մೳͩ ͕ɺ ௨஌Λઃఆ͢Δͷ͸ΞϓϦى ಈத ௨஌ςΩετ ϓϩόΠμଆ͔Β೚ ҙʹมߋՄೳ ΞϓϦ಺෦Ͱઃఆ มߋ͢Δʹ͸ΞϓϦͷόʔδ ϣϯΞοϓ͕ඞཁ

Slide 41

Slide 41 text

໨࣍ • Push / Local Notification ͱ͸ʁ • Push Notification • Local Notification • Push / Local Notificationൺֱ • iOS7ͷػೳ • ·ͱΊ

Slide 42

Slide 42 text

#BDLHSPVOE'FUDI

Slide 43

Slide 43 text

J04·Ͱͷ͓͞Β͍ • ΞϓϦ͕όοΫάϥ΢ϯυʹͳͬͨࡍͷॲཧ͸ Իָ࠶ੜɺҐஔ৘ใऔಘɺVoIPͷΈՄೳ • ͦΕҎ֎͸UIApplicationͷ beginBackgroundTaskWithExpirationHandler: Ͱ όοΫάϥ΢ϯυʹߦ͔ͬͯΒ10෼͚ؒͩॲཧ ͕Մೳͩͬͨɻ10෼ޙʹ͸αεϖϯυ͢Δ

Slide 44

Slide 44 text

#BDLHSPVOE'FUDI • iOS7ͰBackground Modeʹ௥Ճ͞Εͨ • 10෼ͷ੍ݶ͸ͳ͘ͳͬͨ • OS͕࠷దͱ൑அͨ͠λΠϛϯάͰόοΫάϥ΢ ϯυॲཧΛߦ͏ • ݺͼग़͠λΠϛϯά͸ϢʔβʔͷΞϓϦͷར༻ ঢ়گΛΈֶͯश͢Δ

Slide 45

Slide 45 text

3FNPUF/PUJpDBUJPOT • iOS7ͰBackground Modeʹ௥Ճ͞Εͨ • Push NotificationΛΩʔʹόοΫάϥ΢ϯυͰॲ ཧΛ࣮ߦ͢Δ͜ͱ͕Ͱ͖Δ

Slide 46

Slide 46 text

3FNPUFOPUJpDBUJPOT ઃఆํ๏  XcodeͷCapabilitiesઃఆͰBackgroundMode > Remote notificationsʹνΣοΫ

Slide 47

Slide 47 text

UIApplicationDelegateͷԼهͷϝιουΛ࣮૷ - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { // コンテンツのダウンロード処理など ! if (success) { if (hasData) { // データ取得成功 completionHandler(UIBackgroundFetchResultNewData); } else { // データなし completionHandler(UIBackgroundFetchResultNoData); } } else { // データ取得失敗 completionHandler(UIBackgroundFetchResultFailed); } } 3FNPUFOPUJpDBUJPOT ઃఆํ๏ 

Slide 48

Slide 48 text

{ "aps":{ "alert":"hello", "badge":1, "sound":"default", "content-available":1 } } ϓϩόΠμ͕ૹ৴͢ΔQBZMPBEʹzDPOUFOUBWBJMBCMFzΛ௥Ճ͢Δͱ 3FNPUFOPUJpDBUJPOT QBZMPBE - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler ͕࣮ߦ͞ΕΔ

Slide 49

Slide 49 text

{ "aps":{ "content-available":1 } } 4JMFOU1VTI QBZMPBEͷϝοηʔδΛࢦఆͤͣʹzDPOUFOUBWBJMBCMFz͚ͩࢦఆ͢Δͱɺ ௨஌͕දࣔ͞Εͣʹɺॲཧ͚࣮ͩߦ͞ΕΔ 4JMFOU1VTI

Slide 50

Slide 50 text

஫ҙ఺ • όοΫά΢ϯυͰΞϓϦ͕ىಈͯ͠ ͍ͳ͍ͱॲཧ͸ݺͼग़͞Εͳ͍ • iOSͷઃఆͰΞϓϦ͝ͱʹόοΫάϥ ΢ϯυॲཧͷڐՄΛऔΓফ͢͜ͱ͕ Ͱ͖Δ ඞਢػೳͱͯ͠ఏڙ͢Δͷ͸ةݥ

Slide 51

Slide 51 text

໨࣍ • Push / Local Notification ͱ͸ʁ • Push Notification • Local Notification • Push / Local Notificationൺֱ • iOS7ͷػೳ • ·ͱΊ

Slide 52

Slide 52 text

·ͱΊ 1VTI/PUJpDBUJPO • ॳճͷઃఆ΍؀ڥߏங͕໘౗ • ͦΕͰ΋Ϣʔβʔ࠶ར༻཰ΛߴΊΔʹ͸ ඞਢػೳ

Slide 53

Slide 53 text

·ͱΊ -PDBM/PUJpDBUJPO • ઃఆ͕؆୯ • ΧϨϯμʔ΍ToDoΞϓϦͳͲϢʔβʔͱ ͷίϛϡχέʔγϣϯ͕ແ͍ΞϓϦʹ͸ ޲͍ͯΔ

Slide 54

Slide 54 text

·ͱΊ #BDLHSPVOE'FUDI • େ͖ͳσʔλΛಡΈࠐΉΑ͏ͳΞϓϦ͸ Pushͱ૊Έ߹ΘͤΔͱ͍͍͔΋ • όοΫάϥ΢ϯυͰ͔͠ಈ͔ͳ͍ͷͰɺ ඞਢػೳͱ࣮ͯ͠૷͢Δͷ͸ةݥ

Slide 55

Slide 55 text

8"/5&% https://www.wantedly.com/projects/5530 iOS(ʹݶΒͣ) ΤϯδχΞืूதʂ