Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
ios_push_local_notification
Search
WorldDownTown
February 23, 2014
Programming
0
150
ios_push_local_notification
iOS, Objective-C, Push Notification, Local Notification
WorldDownTown
February 23, 2014
Tweet
Share
More Decks by WorldDownTown
See All by WorldDownTown
WWDC動画鑑賞会📹🍱を支える技術 / WWDC Video Lunch
worlddowntown
0
300
Live Renderingとの上手い付き合い方
worlddowntown
1
550
In-App Purchase / Subscription with StoreKit
worlddowntown
3
3k
20150225_iqon.pdf
worlddowntown
0
93
iqon_ios_growth_hack
worlddowntown
3
4.3k
Other Decks in Programming
See All in Programming
「やめとこ」がなくなった — 1月にZennを始めて22本書いた AI共創開発のリアル
atani14
0
370
株式会社 Sun terras カンパニーデック
sunterras
0
2k
LangChain4jとは一味違うLangChain4j-CDI
kazumura
1
170
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
380
猫の手も借りたい!ので AIエージェント猫を作って社内に放した話 Claude Code × Container Lambda の Slack Bot "DevNeko"
naramomi7
0
260
SourceGeneratorのマーカー属性問題について
htkym
0
180
Cyrius ーLinux非依存にコンテナをネイティブ実行する専用OSー
n4mlz
0
120
朝日新聞のデジタル版を支えるGoバックエンド ー価値ある情報をいち早く確実にお届けするために
junkiishida
1
780
Rで始めるML・LLM活用入門
wakamatsu_takumu
0
170
DevinとClaude Code、SREの現場で使い倒してみた件
karia
1
1k
エラーログのマスキングの仕組みづくりに役立ったASTの話
kumoichi
0
160
ポーリング処理廃止によるイベント駆動アーキテクチャへの移行
seitarof
0
110
Featured
See All Featured
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
140
KATA
mclloyd
PRO
35
15k
Fireside Chat
paigeccino
42
3.8k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
19k
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
0
250
Measuring & Analyzing Core Web Vitals
bluesmoon
9
780
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
2
150
Building AI with AI
inesmontani
PRO
1
780
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
Statistics for Hackers
jakevdp
799
230k
A Tale of Four Properties
chriscoyier
163
24k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
231
22k
Transcript
1VTI-PDBM /PUJpDBUJPO ͱͦͷपล 2014/2/23 ঙ࢘ ܒี
ࣗݾհ • ঙ࢘ ܒี • twitter/github: WorldDownTown • iOSྺ1 iQONͷiOSΤϯδχΞ
J20/
J20/ ϑΝογϣϯࡶࢽΛݟΔΑ͏ʹτϨϯυ͕Θ͔ͬͯɺ ݟ͍ͯΔͷ͕௨ൢͰ͖ΔແྉͷϑΝογϣϯ ίʔσΟωʔτΞϓϦ AppStoreͷ2012ϕετΞϓϦʹબग़ʂ
࣍ • Push / Local Notification ͱʁ • Push Notification
• Local Notification • Push / Local Notificationൺֱ • iOS7ͷػೳ • ·ͱΊ
Push / Local Notification ͬͯ·͔͢ʁ
Push / Local Notification ͱʁ
Push / Local Notification ͱʁ ϩʔΧϧ௨͓Αͼϓογϡ௨͕ղܾ͢Δ ϑΥΞάϥϯυͰɺʹͭͷΞϓϦέʔγϣϯ͔͠ΞΫςΟϒʹͳΕ·ͤΜɻ ଟ͘ͷΞϓϦέʔγϣϯɺ࣌ؒϕʔε·ͨ૬ޓଓ͞ΕͨڥͰಈ࡞͍ͯ͠Δͨ ΊɺΞϓϦέʔγϣϯ͕ϑΥΞάϥϯυʹͳ͍ͱ͖ʹɺϢʔβ͕ؔ৺Λ͍࣋ͬͯΔ Πϕϯτ͕ൃੜ͢ΔՄೳੑ͕͋Γ·͢ɻ
ϩʔΧϧ௨͓Αͼϓογϡ௨ʹΑΓɺΞϓϦέʔγϣϯɺ͜ΕΒͷΠϕϯτ͕ ൃੜͨ͜͠ͱΛϢʔβʹ௨Ͱ͖ΔΑ͏ʹͳΓ·͢ɻ ʰ-PDBM͓Αͼ1VTI/PUJpDBUJPOϓϩάϥϛϯάΨΠυʱ
Push / Local Notification ͱʁ ϩʔΧϧ௨͓Αͼϓογϡ௨͕ղܾ͢Δ ϑΥΞάϥϯυͰɺʹͭͷΞϓϦέʔγϣϯ͔͠ΞΫςΟϒʹͳΕ·ͤΜɻ ଟ͘ͷΞϓϦέʔγϣϯɺ࣌ؒϕʔε·ͨ૬ޓଓ͞ΕͨڥͰಈ࡞͍ͯ͠Δͨ ΊɺΞϓϦέʔγϣϯ͕ϑΥΞάϥϯυʹͳ͍ͱ͖ʹɺϢʔβ͕ؔ৺Λ͍࣋ͬͯΔ Πϕϯτ͕ൃੜ͢ΔՄೳੑ͕͋Γ·͢ɻ
ϩʔΧϧ௨͓Αͼϓογϡ௨ʹΑΓɺΞϓϦέʔγϣϯɺ͜ΕΒͷΠϕϯτ͕ ൃੜͨ͜͠ͱΛϢʔβʹ௨Ͱ͖ΔΑ͏ʹͳΓ·͢ɻ ʰ-PDBM͓Αͼ1VTI/PUJpDBUJPOϓϩάϥϛϯάΨΠυʱ ར༻্ʹͭͳ͕Δ
Push / Local Notification ͱʁ • ܯࠂόφʔ͕දࣔ͞ΕΔ • ΞϓϦέʔγϣϯΞΠίϯʹόοδ͕ͭ͘ •
αϯυ͕໐Δ Ϣʔβʔʹͱͬͯ Push NotificationLocal Notification ಉ͡ʹݟ͑Δ
Push / Local Notification ͱʁ • ࣮ํ๏ͷҧ͍ • ϝϦοτ/σϝϦοτͷҧ͍ ΞϓϦέʔγϣϯʹͱͬͯ
Push NotificationͱLocal Notification ҧ͏ʹݟ͑Δ
࣍ • Push / Local Notification ͱʁ • Push Notification
• Local Notification • Push / Local Notificationൺֱ • iOS7ͷػೳ • ·ͱΊ
1VTI/PUJpDBUJPO
1VTI/PUJpDBUJPO • iPhone OS 3.0ʙ • αʔό͔ΒiOS௨ΛૹΔ • αʔό͔Βҙͷϝοηʔδ/λΠϛϯά Ͱૹ৴Մೳ
1VTI/PUJpDBUJPOͷΈ 1. Apple Push Notification Service (APNs) ͱ͍͏ήʔτΣΠʹσόΠε Λొ
2. σόΠε͕APNs͔ΒdeviceTokenΛड͚औΔ 3. ΞϓϦ͕σόΠε͔ΒdeviceTokenΛड͚औΔ 4. deviceTokenΛϓϩόΠμ(ΞϓϦ ӡӦऀͷαʔό)ʹొ͢Δ
1VTI/PUJpDBUJPOͷΈ 1. ϓϩόΠμdeviceTokenͱpayloadΛؚΉ௨ύοέʔδΛ࡞ ϦϞʔτ௨ͷσʔλҰํʹྲྀΕΔ 2. ϓϩόΠμͦͷ௨ΛAPNsʹૹ৴ 3. APNs͕ͦͷ௨ΛσόΠεʹ৴ʢϓογϡʣ
1VTI/PUJpDBUJPOΛૹΔ ४උ • ϓϩόΠμͷڥߏங • σόΠετʔΫϯઃఆॲཧ࣮
ϓϩόΠμͷڥߏங লུ
ϓϩόΠμͷڥߏங ໘ͳڥઃఆΛ͠ͳ͍͍ͯ͘Α͏ʹͳ͖ͬͯ·ͨ͠
- (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ͷԼهͷϝιουΛ࣮
͜ΕͰ४උྃ ϓϩόΠμ͔Β 1VTIૹ৴Մೳ
Ԡ༻ • payloadͷΧελϜϓϩύςΟ • σόΠετʔΫϯઃఆλΠϛϯά
QBZMPBEͷΧελϚΠζ { "aps":{ "alert":"hello", "badge":1, "sound":"default" } } γϯϓϧͳQBZMPBE
QBZMPBEͷΧελϚΠζ { "aps":{ "alert":{ "body":"hello", "action-loc-key":"ゲームを再開", "launch-image":"push.png" }, "badge":1, "sound":"default"
} } BMFSUͷࢠϓϩύςΟͰΧελϚΠζͰ͖Δ
QBZMPBEͷΧελϚΠζ BMFSUͷࢠϓϩύςΟ Ωʔ ͷܕ આ໌ CPEZ จࣈྻ 1VTI௨࣌ͷϝοηʔδ BDUJPOMPDLFZ จࣈྻ
1VTIىಈϘλϯͷϝοηʔδ MPDLFZ จࣈྻ 1VTI௨࣌ͷϩʔΧϥΠζϝοηʔδ -PDBMJ[BCMFTUSJOHTϑΝΠϧͷΩʔΛ༩͑Δ MPDBSHT จࣈྻͷྻ MPDLFZͷॻࣜࢦఆࢠͷΘΓʹ දࣔ͢Δมจࣈྻ MBVODIJNBHF จࣈྻ 1VTI͔Βͷىಈ࣌ʹදࣔ͞ΕΔը૾ͷϑΝΠϧ໊ ࢦఆ͠ͳ͚Ε%FGBVMUQOH
QBZMPBEͷΧελϚΠζ BDUJPOMPDLFZ
QBZMPBEͷΧελϚΠζ { "aps":{ "alert":"hello", "badge":1, "sound":"default" }, "key":"value" } ΞϓϦέʔγϣϯʹLFZWBMVFΛ͢͜ͱ͕Ͱ͖Δ
Push௨ىಈͷϩάΛམͱͨ͠Γ! ىಈ࣌ͷViewControllerΛࢦఆͨ͠ΓͰ͖Δ
- (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ͷΧελϚΠζ
σόΠετʔΫϯઃఆͷ λΠϛϯά - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // APNsにデバイス登録
UIRemoteNotificationType notificationType = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert; [[UIApplication sharedApplication] registerForRemoteNotificationTypes:notificationType]; ! return YES; } Α͘ݟΔαϯϓϧ
σόΠετʔΫϯઃఆͷ λΠϛϯά ·ͩͲΜͳΞϓϦ͔Α͘Θ͔Βͳ͍ͷʹɺ! ॳճىಈͷλΠϛϯάͰϓογϡͷڐՄ! Λฉ͍ͯ͠·͏ͱڐՄͯ͠Β͑ͳ͍…
σόΠετʔΫϯઃఆͷ λΠϛϯά νϡʔτϦΞϧʹ͋ΔΑ͏ʹ! application:didFinishLaunchingWithOptions: Ͱ! registerForRemoteNotificationTypesΛίʔϧͤͣɺ! ϓογϡ௨Λड͚औΔϝϦοτड़ͨ͏͑Ͱ! ॳΊͯregisterForRemoteNotificationTypes:Λίʔϧ͢Δ iQONͰPUSHઃఆ্͕!
࣍ • Push / Local Notification ͱʁ • Push Notification
• Local Notification • Push / Local Notificationൺֱ • iOS7ͷػೳ • ·ͱΊ
-PDBM/PUJpDBUJPO • iOS 4.0ʙ • ໘ͳϓϩόΠμઃఆ͕ෆཁ • λΠϚʔ܁Γฦ͠Ͱ௨ΛදࣔͰ͖Δ • ΞϓϦ͕OSʹରͯ͠௨ͷεέδϡʔϧ
ςΩετΛઃఆ͢Δ
௨ઃఆ 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ͱಉ͡Α͏ͳࡉ͔͍Φϓγϣϯ͋Δ
௨Ωϟϯηϧ NSArray *notifications = [UIApplication sharedApplication].scheduledLocalNotifications; for (UILocalNotification *notification in
notifications) { if ([notification.userInfo[@"id"] integerValue] == 1234) { [[UIApplication sharedApplication] cancelLocalNotification:notification]; } } ΧϨϯμʔΞϓϦͰεέδϡʔϧΛআ࣌͠ͳͲɺ! ௨ΛΩϟϯηϧ͢Δ͜ͱ͕Ͱ͖Δ [[UIApplication sharedApplication] cancelAllLocalNotifications]; શͯͷ௨ΛΩϟϯηϧ ಛఆͷ௨ΛΩϟϯηϧ͢ΔʹuserInfoͷใ͔ΒΩϟϯηϧ͢Δ௨Λಛఆ͢Δ
- (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ͱ΄΅ಉ͡) ىಈ࣌ͷ੍ޚ
-PDBM/PUJpDBUJPOԠ༻ྫ Sleipnir͕νϡʔτϦΞϧͱͯ͠Local Notification! Λར༻͍ͯ͠Δ
-PDBM/PUJpDBUJPOԠ༻ྫ ࣮Λ૾ͯ͠Έͨ • AppDelegateͷapplicationWillResignActive:Ͱ௨ͷઃఆ • notification.soundName = nil; • νϡʔτϦΞϧͱ͍ͯ͑ͨ͠ػೳΛطʹͬͨ͜ͱ͕
͋Δ߹ɺ௨ΛΩϟϯηϧ
࣍ • Push / Local Notification ͱʁ • Push Notification
• Local Notification • Push / Local Notificationൺֱ • iOS7ͷػೳ • ·ͱΊ
1VTI-PDBM/PUJpDBUJPOൺ ֱ 1VTI/PUJpDBUJPO -PDBM/PUJpDBUJPO ઃఆڥߏங ϓϩόΠμڥ 1SPWJTJPOJOHͷઃఆ͕ ඞཁ ωΠςΟϒͷίʔυ ͷΈ
௨λΠϛϯά ϓϩόΠμଆ͔Β ҙʹมߋՄೳ εέδϡʔϦϯά͕Մೳͩ ͕ɺ ௨Λઃఆ͢ΔͷΞϓϦى ಈத ௨ςΩετ ϓϩόΠμଆ͔Β ҙʹมߋՄೳ ΞϓϦ෦Ͱઃఆ มߋ͢ΔʹΞϓϦͷόʔδ ϣϯΞοϓ͕ඞཁ
࣍ • Push / Local Notification ͱʁ • Push Notification
• Local Notification • Push / Local Notificationൺֱ • iOS7ͷػೳ • ·ͱΊ
#BDLHSPVOE'FUDI
J04·Ͱͷ͓͞Β͍ • ΞϓϦ͕όοΫάϥϯυʹͳͬͨࡍͷॲཧ Իָ࠶ੜɺҐஔใऔಘɺVoIPͷΈՄೳ • ͦΕҎ֎UIApplicationͷ beginBackgroundTaskWithExpirationHandler: Ͱ όοΫάϥϯυʹߦ͔ͬͯΒ10͚ؒͩॲཧ ͕Մೳͩͬͨɻ10ޙʹαεϖϯυ͢Δ
#BDLHSPVOE'FUDI • iOS7ͰBackground ModeʹՃ͞Εͨ • 10ͷ੍ݶͳ͘ͳͬͨ • OS͕࠷దͱஅͨ͠λΠϛϯάͰόοΫάϥ ϯυॲཧΛߦ͏ •
ݺͼग़͠λΠϛϯάϢʔβʔͷΞϓϦͷར༻ ঢ়گΛΈֶͯश͢Δ
3FNPUF/PUJpDBUJPOT • iOS7ͰBackground ModeʹՃ͞Εͨ • Push NotificationΛΩʔʹόοΫάϥϯυͰॲ ཧΛ࣮ߦ͢Δ͜ͱ͕Ͱ͖Δ
3FNPUFOPUJpDBUJPOT ઃఆํ๏ XcodeͷCapabilitiesઃఆͰBackgroundMode > Remote notificationsʹνΣοΫ
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 ઃఆํ๏
{ "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 ͕࣮ߦ͞ΕΔ
{ "aps":{ "content-available":1 } } 4JMFOU1VTI QBZMPBEͷϝοηʔδΛࢦఆͤͣʹzDPOUFOUBWBJMBCMFz͚ͩࢦఆ͢Δͱɺ ௨͕දࣔ͞Εͣʹɺॲཧ͚࣮ͩߦ͞ΕΔ 4JMFOU1VTI
ҙ • όοΫάϯυͰΞϓϦ͕ىಈͯ͠ ͍ͳ͍ͱॲཧݺͼग़͞Εͳ͍ • iOSͷઃఆͰΞϓϦ͝ͱʹόοΫάϥ ϯυॲཧͷڐՄΛऔΓফ͢͜ͱ͕ Ͱ͖Δ ඞਢػೳͱͯ͠ఏڙ͢Δͷةݥ
࣍ • Push / Local Notification ͱʁ • Push Notification
• Local Notification • Push / Local Notificationൺֱ • iOS7ͷػೳ • ·ͱΊ
·ͱΊ 1VTI/PUJpDBUJPO • ॳճͷઃఆڥߏங͕໘ • ͦΕͰϢʔβʔ࠶ར༻ΛߴΊΔʹ ඞਢػೳ
·ͱΊ -PDBM/PUJpDBUJPO • ઃఆ͕؆୯ • ΧϨϯμʔToDoΞϓϦͳͲϢʔβʔͱ ͷίϛϡχέʔγϣϯ͕ແ͍ΞϓϦʹ ͍ͯΔ
·ͱΊ #BDLHSPVOE'FUDI • େ͖ͳσʔλΛಡΈࠐΉΑ͏ͳΞϓϦ PushͱΈ߹ΘͤΔͱ͍͍͔ • όοΫάϥϯυͰ͔͠ಈ͔ͳ͍ͷͰɺ ඞਢػೳͱ࣮ͯ͢͠Δͷةݥ
8"/5&% https://www.wantedly.com/projects/5530 iOS(ʹݶΒͣ) ΤϯδχΞืूதʂ