Trying to force Handoff functionality to work on iPhone 5 and iPad Air with iOS 9 devices and encounter issues that I think is iOS9-related - cannot check on iOS 8 because I have no devices with this system.
Problem:
- I am opening app on first device when main screen when user activity is created
- On second device I see on lock screen that there is some activity related to my app
- I am opening this app and
application:continueUserActivity:restorationHandler:
is not called on this device so I have no ability to show to user the same content which was presented on the first device.
You can browse entire project on github: https://github.com/tomkowz/Quotes
Implementation details:
I've updated target's plist file and added NSUserActivityTypes
.
<key>NSUserActivityTypes</key>
<array>
<string>com.tomaszszulc.Quotes.quotesList</string>
<string>com.tomaszszulc.Quotes.browseQuote</string>
</array>
Next I've created enum with these declared types:
enum ActivityType: String {
case BrowseQuote = "com.tomaszszulc.Quotes.browseQuote"
case QuotesList = "com.tomaszszulc.Quotes.quotesList"
}
When user is on the main screen I'm starting NSUserActivity
.
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
quotes = Quote.findAll(CoreDataStack.sharedInstance().mainContext)
tableView.reloadData()
startUserActivity()
}
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
userActivity?.invalidate()
}
func startUserActivity() {
let activity = NSUserActivity(activityType: ActivityType.QuotesList.rawValue)
activity.title = "Viewing Quotes List"
userActivity = activity
userActivity?.becomeCurrent()
}
The second type of activity activates when user goes to details of selected item. Here is the views flow:
UINavigationController -> (root) QuotesListViewController -> (push) QuoteDetailsViewController
Here is the code for creating user activity in QuoteDetailsViewController
:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
userActivity = viewModel.userActivity // (viewModel) quote.userActivity
userActivity?.becomeCurrent()
}
override func viewDidDisappear(animated: Bool) {
super.viewDidDisappear(animated)
userActivity?.invalidate()
}
And the viewModel.userActivity
calls:
extension Quote {
@available(iOS 8.0, *)
var userActivity: NSUserActivity {
let activity = NSUserActivity(activityType: ActivityType.BrowseQuote.rawValue)
activity.title = "Reading " + self.author + " quote"
activity.userInfo = [QuoteUserActivityKey.Identifier.rawValue: self.identifier]
// Core Spotlight support
if #available(iOS 9.0, *) {
activity.contentAttributeSet = self.searchableItemAttributeSet()
activity.keywords = Set([self.author])
activity.eligibleForSearch = true
activity.eligibleForHandoff = true
}
return activity
}
}
Thank you in advance!