ããã«ã¡ã¯ãã¢ãã¤ã«ãã¡ã¼ã¹ã室ã®ä¸æ(@_nkmrh)ã§ãã
çªç¶ã§ãããMacä¸ã§æ¢ããã¬ã·ããããiPhoneã§è¦ãããã¨ä¾¿å©ã ã¨æãã¾ãããï¼
å æ¥ãªãªã¼ã¹ããiOSã¯ãã¯ãããã¢ããªã§ã¯ãããåºæ¥ãããã«ãªãã¾ããã
ã¨ã¦ã便å©ãªã®ã§ãã²æ´»ç¨ãã¦ãã ããã
â» å®ã¯ãã®ä¾¿å©æ©è½ã次ã®ãã¼ã¸ã§ã³ã§ä¸æ¦åãä¸ããåé¡ã解決ãããã¨ã§å度å°å ¥ãããã¨ã«ãªãã¾ããã以éã®è¨äºã§äºæ ã説æãã¾ãã
- Mac OS X Yosemiteãã¤ã³ã¹ãã¼ã«ãããMacãiOS 8ãã¤ã³ã¹ãã¼ã«ãããiPhone 5以éãiPad 第4ä¸ä»£ãiPad AirãiPad miniãiPad mini Retinaãã£ã¹ãã¬ã¤ã¢ãã«ãiPod touch 第5ä¸ä»£ã§ãå©ç¨ããã ãã¾ãã
- Macã¨iPhoneã«åãiCloudã¢ã«ã¦ã³ããè¨å®ãã¦ä¸ããã
ããããã®æ§å...ã
Macä¸ã®Safariã§ã¯ãã¯ããããµã¤ããéãã¦ã¬ã·ããæ¢ãã¾ãã
ããã¨...ãiPhoneã®ããã¯ç»é¢ã®å·¦ä¸ã«ã¯ãã¯ãããã®ã¢ã¤ã³ã³ã表示ããã¾ãã

å·¦ä¸ã«ã¯ãã¯ãããã¢ã¤ã³ã³ã...ã

ã¢ã¤ã³ã³ãã¹ã¯ã¤ãããã¨...ã
ã
ãªãã¨...ãMacã§è¡¨ç¤ºãã¦ããã¬ã·ããã¯ãã¯ãããã¢ããªã§è¡¨ç¤ºããã¾ãã...ã 便å©ã£ï¼ï¼

ãã®ããã«ä¾¿å©ãªã®ã§ãããã¢ããªãªãªã¼ã¹å¾ããã®æ©è½ã«ã¯åé¡ããããã¨ããããã¾ããã
Handoffã®åé¡ç¹
ã¢ããªããªãªã¼ã¹ãããç¿æ¥ã12/05 ã® 0:00 ã« ãµã¼ãã¼ã¸ã®ã¢ã¯ã»ã¹ãæ¥å¢ããæãåããªãç¶æ ã«ãªãã¾ããã 調æ»ããã¨ããããã®1ç§ãããã®éã« "/apple-app-site-association" ã¨ãããã¡ã¤ã«ã«å¯¾ãã¦ãæ®æ®µã®40åãããã®ã¢ã¯ã»ã¹ãããã¾ããã
apple-app-site-association ã¸ã®ã¢ã¯ã»ã¹ã¯ã¤ã³ã¹ãã¼ã«æã«è¡ããã¾ãã ã¤ã³ã¹ãã¼ã«ã¨ããã®ã¯ ååã¤ã³ã¹ãã¼ã«æã ãã§ã¯ãªããã¢ãããã¼ããå«ã¿ã¾ãã ãã®ã¿ã¤ãã³ã°ã¯ã¤ã³ã¹ãã¼ã« or ã¢ãããã¼ããçµãã£ãã¿ã¤ãã³ã°ã§ãOS ã®ãã¼ã¢ã³ (swcd) ã«ãã£ã¦ãªã¯ã¨ã¹ãããã¾ãã
ã¨ããã§ãiOS ã«ã¯ã¢ããªã®èªåã¢ãããã¼ãæ©è½ãããã¾ãã ã¨ããããã§ããã®èªåã¢ãããã¼ãã 0:00 ã«åããä¸æã« /apple-app-site-association ã«ã¢ã¯ã»ã¹ãæ¥ã¦ããã®ã§ã¯ãã¨åå ãæ¨æ¸¬ãã¾ããã ã¢ã¯ã»ã¹ã¯ Apple çµç±ã§ã¯ãªã iOS 端æ«ããããããæ¥ã¦ãããããã¢ããªã®ãªãªã¼ã¹å¾ãæ¯å 0:00 ã«ãã®ãã¡ã¤ã«ã«å¯¾ãã¦å¤§éã®ã¢ã¯ã»ã¹ãæ¥ãç¶æ³ã«ãªãã¾ããã (ãã¡ãã1端æ«1ãªã¯ã¨ã¹ããããªãã®ã§ããã©ãã£ãã¯ã¨ãã¦ã¯å¤§ãããã¨ãªãã®ã§ãã)
ã¢ããã«ã®ãã¯ãã«ã«ãµãã¼ãã¸ãã®ä»¶ã«ã¤ãã¦åãåããããã¨ããæ¬¡ã®ãããªè¿çãããã¾ããã
è¿çãè¦è¨³ããã¨ãã¢ããªã®ã¤ã³ã¹ãã¼ã«ãåã¤ã³ã¹ãã¼ã«ãã¢ãããã¼ãæã«/apple-app-site-associationã«ã¢ã¯ã»ã¹ãã¾ããèªåã¢ãããã¼ãã®æéã¯æ±ºã¾ã£ã¦ãªããã©ãã°ã©ããè¦ãã°ãªã¯ã¨ã¹ãæ°äºæ³ã§ãã¾ããï¼ã¢ããªãã¢ãããã¼ãããã¹ã±ã¸ã¥ã¼ã«ã«å¿ãã¦ããµã¼ãã¼ã«ã©ããããã®è² è·ãããããäºæ¸¬ãã¦ä¸ãããã¨ããæ¨ã®ããã·ãè¿çã§ãã...
ããã«å¯¾ãã¦ããªã¯ã¨ã¹ãã®æéã忣ãããçã®å¯¾çããé¡ãããã¨ãããhttps://developer.apple.com/bug-reporting/ ã«Bug Reportãéã£ã¦ã»ããã¨ã®åçã ã£ããããBug Reportãéãã¾ããã
ãã®ãããªçµç·¯ã®ãããiOSã¯ãã¯ãããã¢ããªã®æ¬¡ã®ãã¼ã¸ã§ã³ã§ã¯ä¸åº¦Handoffæ©è½ãåãä¸ãã大éãªã¯ã¨ã¹ãã«åãããã¥ã¼ãã³ã°ãããä¸ã§æ¥å¹´å度å°å ¥ãããã¨ã«ãã¾ããã
ããã¾ã§é·ããªãã¾ããããããã§ãHandoffå®è£ ããããã¨ããæ¹ã¸ã以éHandoffã®å ·ä½çãªå®è£ æ¹æ³çãç´¹ä»ãã¾ãã
iOS 8ã®æ°æ©è½Handoff
Handoffã¯iOS 8ã¨Mac OS X Yosemiteããã¤ãããããã«ãªã£ãæ©è½ã§ããBluetooth Low Energy(以ä¸ãBLE)æè¡ãã¤ãããiPhoneãiPad, Macéã§ãã¼ã¿ã®éåä¿¡ãå®ç¾ãã¦ãã¾ãã
â» BLEã§ä¸åº¦ã«éåä¿¡ã§ãããã¼ã¿ãµã¤ãºã¯ã3KB以ä¸ã§ãããã以ä¸ã®ãã¼ã¿ã¯ã¹ããªã¼ãã³ã°è»¢éããããã¨ãã§ãã¾ãã
ããã¤ã¹ã®è¨å®
- Handoffã«å¯¾å¿ããOSãã¤ã³ã¹ãã¼ã«ãããiPhoneãiPad, Macã®iCloudã¢ã«ã¦ã³ãããåä¸ã®ã¢ã«ã¦ã³ãã«è¨å®ãã¾ãã
- iOSã§ã¯
è¨å®.app > ä¸è¬ > Handoffã¨åè£ã®AppããHandoffãONã«ãã¾ãã - Macã§ã¯
ã·ã¹ãã ç°å¢è¨å® > ä¸è¬ããHandoffãæå¹ã«ãããã§ãã¯ããã¯ã¹ãONã«ãã¾ãã
å®è£
ä»åã¯ä¸è¨ã§ç´¹ä»ããããã«ãMacã®Safariã§éãã¦ããWebãµã¤ãããiPhoneã¢ããªã«é·ç§»ãããæ¹æ³ãç´¹ä»ãã¾ããiOSéã®å®è£ ãåºæ¬çã«ã¯åãã§ãã
apple-app-site-association
apple-app-site-associationãã¡ã¤ã«ã使ãã¾ãã ãã®ãã¡ã¤ã«ã¯ãWebãµã¤ãã®ã«ã¼ãã«é ç½®ãã¦ãããã®ã§ã飿ºããã¢ããªã®App Idãè¨è¿°ãããã¡ã¤ã«ãAppleãèªå¯ããè¨¼ææ¸ã§ç½²åãããã®ã§ãã
- handoff.jsonãã¡ã¤ã«ã使ãã以ä¸ã®å 容ãè¨è¿°ãã¾ãã
{"activitycontinuation":{"apps":["XXXXXXXXXX.com.example.myapp"]}}
ï¼XXXXXXXXXXã®é¨åã¯App Id Prefixãæå®ãã¾ããï¼
- .p12ãã¡ã¤ã«ãKeychain Access.appããæ¸ãåºãã¾ããiPhone Developerã®è¨¼ææ¸ãå³ã¯ãªãã¯ã§é¸æãæ¸ãåºãã鏿ãã¾ãã
Certificates > iPhone Distribution: \<name\> xxx > Certificates.p12
- opensslã³ãã³ãã§è¨¼ææ¸ã使ãã¾ãã
openssl pkcs12 -in Certificates.p12 -clcerts -nokeys -out output_crt.pem
- ç§å¯éµã使ãã¾ãã
openssl pkcs12 -in Certificates.p12 -nocerts -nodes -out output_key.pem
- ä¸éè¨¼ææ¸ã使ãã¾ãã
openssl pkcs12 -in Certificates.p12 -cacerts -nokeys -out sample.ca-bundle
- handoff.jsonãã¡ã¤ã«ãä¸è¨ã®ã³ãã³ãã§ç½²åãã¾ãã
cat handoff.json | openssl smime -sign -inkey output_key.pem -signer output_crt.pem -certfile sample.ca-bundle -noattr -nodetach -outform DER > apple-app-site-association
- apple-app-site-associationãWebãµã¤ãã®ã«ã¼ãã«é ç½®ãã¾ãã
Xcodeã®è¨å®
- Info.plistã«NSUserActivityTypesããããã£ã追å ãã¾ããTypeã«
Arrayãæå®ãå¤ãcom.example.${PRODUCT_NAME:rfc1034identifier}.activityTypeã«è¨å®ãã¾ããï¼â» ActivityTypeã¯ä»»æã®æååã§ããï¼ Target > Capabilities > Entitlements Associated Domainsãæå¹ONã«ãå¤ãactivitycontinuation:example.comã«è¨å®ãã¾ãã
ã¢ããªã®å®è£
iOS SDK 8.0ããapplication delegate protocolã¨UIResponderã¯ã©ã¹ã«Handoffç¨ã®ã¡ã½ããã追å ããã¦ãã¾ãã
optional func application(_ application: NSApplication,willContinueUserActivityWithType userActivityType: String) -> Bool
application delegate protocol ã«è¿½å ãããã¡ã½ããã§ãã弿°ã®NSUserActivityãªãã¸ã§ã¯ãã®å¤ãè¦ã¦ãHandoffã®å¿çã«å¿ãããç¡è¦ããããè¿ãããã«ãã¾ãã
optional func application(_ application: NSApplication, continueUserActivity userActivity:NSUserActivity, restorationHandler restorationHandler: ([AnyObject]!) -> Void) -> Bool
application delegate protocol ã«è¿½å ãããã¡ã½ããã§ããHandoffããèµ·åããéã«å¼ã°ãã¾ãã弿°ã§æ¸¡ã£ã¦ããblockã®å¼æ°ã«ViewControllerã®Arrayãæ¸¡ããã¨ã§ViewControllerã®-restoreUserActivityState:ã¡ã½ãããå¼ã°ãã¾ããHandoffããèµ·åããéã®å¦çã¯ãã®ã¡ã½ããã«å®è£
ãã¾ãã
func restoreUserActivityState(_ activity: NSUserActivity)
UIResponderã¯ã©ã¹ã«è¿½å ãããã¡ã½ããã§ãããã®ã¡ã½ãããViewControllerã«å®è£ ãã¾ããHandoffã§èµ·åããéã«NSUserActivityãªãã¸ã§ã¯ããåãåããã¨ãã§ãã¾ãã
å®è£ ä¾
// application delegate func application(application: UIApplication, willContinueUserActivityWithType userActivityType: String) -> Bool { // trueãè¿ããå ´åã application:continueUserActivity:restorationHandler: ãå¼ã°ãã¾ã // falseãè¿ããå ´åã Handoffã®å¿çãç¡è¦ãã¾ã // userActivityTypeã¯info.plistã®NSUserActivityTypesããããã£ã«æå®ããæååã§ã if userActivityType == "myType" { return true } return false } func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([AnyObject]!) -> Void) -> Bool { // ããã§userActivityã®URLã調ã¹ã¦Handoffã§èµ·åãããã©ããå¤å®ãã¾ã var urlString = userActivity.webpageURL?.absoluteString; if urlString == "xxxxx" { // block弿°ã«myViewcontrollerã®restoreActivityStateãå¼ã°ãã¾ã restorationHandler([Viewcontroller]) return true } return false }
// ViewController func restoreUserActivityState(activity: NSUserActivity) { // Handoffããèµ·åå¾ã«è¡ãå¦çãå®è£ ãã¾ã // Safariããèµ·åããå ´åãwebpageURLããããã£ããSafariã§éãã¦ããURLãåå¾ã§ãã¾ã if let recipeID = activity.webpageURL?.lastPathComponent.toInt() { self.showRecipe(recipeID) } }
ãããã«
ãããã§ããããã以ä¸ã®æé ã§Webãµã¤ãã¨ã¢ããªéã®é£æºãå®ç¾ãããã¨ãã§ãã¾ãã便å©ãªæ©è½ã§ãã®ã§èå³ã®ããæ¹ã¯ãã²è©¦ãã¦ã¿ã¦ãã ããã
åèURL