I am trying to build an app that supports multiple complication families on watch OS2 like modular large, utilitarian large, circular small etc, each showing various meaningful information from the app. I know complications is little similar to the glances we have since OS1 in terms of user interaction i.e, it opens the app on user clicking on it and no special interaction over there.
In glance I was able to do a deep link to the app based on current glance content but I am looking for a way to do the same with complications.
So my question is when the user clicks on my app's complication will I get any sort of context information saying this complication was clicked etc.
I am thinking like if I may get a CLKComplication Object in the context.
Any help is appreciated.
In ClockKit/CLKDefines.h you can find the CLKLaunchedTimelineEntryDateKey constant.
But you can't define your own user info to help you determine what to do when your app is launched.
From the CLKComplicationDataSource Protocol Reference:
CLKLaunchedTimelineEntryDateKey
A key indicating the date with which the complication was launched. The value of this key is an NSDate object. When the user taps your complication, ClockKit includes this key in the dictionary passed to the handleUserActivity: method of the extension delegate.
Available in watchOS 2.0 and later.
Since you can get the tapped timeline entry's date via CLKLaunchedTimelineEntryDateKey, you can get the complication type (family) by making "fixed second" for specific type's timeline entry.
Fixed second should be calculated by NSDateComponents and then convert to NSDate that you can pass to CLKComplicationTimelineEntry.
For example, you can specify modularSmall entry's date end with 10 seconds but modularLarge entry's date end with 20 seconds. So, tapped entry with date 9:41:10 AM should be a modularSmall type, and entry with date 9:41:20 AM should be a modularLarge type.
Related
I am working on an mobile app that requires me to change the text displayed either on a weekly or a monthly basis, but I don't want to require the users to have to update the app every day or every week in order to see the changes. I would love suggestions on how to do this.
As a high-level answer, check the device date and display the proper text, if it is fixed and known ahead of time.
If not, have a file or api call send down the information and the next date of when the server should be checked for the next set of data.
The documentation says that an app can ask a User three times per year via SKSToreReviewController to place a rating.
Most suggest to save a variable in UserDefaults and call the function after a couple of uses. What happens if you call the function more than three times per year? Will the App Store just ignore the calls and after a year asks for a rating again or will you get some kind of error?
And what happens if the app has been updated (ie. a jump from version 1.0 to version 2.0)? Will the 3 requests be reset?
In short, you choose the appropriate time to display the alert, but the system will decide whether to actually show the alert or not. So don't worry about "over-calling" as long as you don't call it as a response to user interaction.
Although you should call this method when it makes sense in the user experience flow of your app, the actual display of a rating/review request view is governed by App Store policy. Because this method may or may not present an alert, it's not appropriate to call it in response to a button tap or other user action.
Highlight mine.
https://developer.apple.com/documentation/storekit/skstorereviewcontroller/2851536-requestreview
As for your second question, the only reference I can find regarding how many times it might be displayed is "3 times per year". It doesn't mention 3 times per app version or update. Use this API wisely.
I've assumed that putting NSBluetoothPeripheralUsageDescription into info.plist will automatically trigger the alert view (at appropriate time) which will among the other things, show the (localized) error defined in InfoPlist.strings(current language). I assumed something like that, because of this statement from the docs:
NSBluetoothPeripheralUsageDescription (String - iOS) This key lets
you describe the reason your app uses Bluetooth. When the system
prompts the user to allow usage, the value that you provide for this
key is displayed as part of the alert.
Take a look at into this part:
When the system prompts the user to allow usage ...
IMO, this means that alert will be popped out automatically, rather than manually in the code by me.
I am using :
CoreBluetooth framework and many of its classes like:
CBPeripheral, CBCharacteristic, CBCentralManager etc. so I guess this alert should pop out. Of course, I can pop out the alert view by myself on the first use of Bluetooth, but I thought that point of these info.plist keys is, actually to warn the user automatically...
Not quite...
I would hate to have iOS automatically pop up every permission request dialog when the app first runs. Much better to allow me to show "Can I use the camera?" the first time the user gets to the section of my app where the camera is used, and "Can I use Bluetooth" when that section is used.
So, the strings are required so the users are not presented with generic "App wants to use Bluetooth" requests. Instead, you have to provide a suitably informative string (subject to the reviewer's opinion, of course).
But it won't be presented to the user until you want it to be shown.
Maybe you already answered the system popup and have an entry in the iOS settings? In this case iOS will not ask anymore.
The calendarIdentifier property on EKCalendar says that a full sync will lose the identifier. How are we supposed to track a calendar then? It's not possible to just trust the name of the calendar because nothing prevents the user from changing the name. Not only that, nothing prevents two calendars from having the same name.
What I'm basically dealing with is that my Team object has an associated subscribed calendar, and I need a way to link those two together. The obvious solution is to store the calendarIdentifier in the Team object once it's created, but that won't work based on the documentation.
According to the Apple Watch Programming Guide, developers are only allowed to include 1 glance in their AppleWatch app. This creates a bit of a challenge for me since my app is an aggregate of different types of data so I'm not sure which data set to include in the glance.
That being said, could I get around this by creating multiple AppleWatch apps for my iOS app which would then allow me to create a single glance for each AppleWatch app?
No. Confirmed one Watch app per iOS app.
There is no support for multiple WatchKit apps per iPhone app at this
time.
- Apple's WatchKit Evangelist
You can implement multiple Glance views depending on the user's context (time and location) using WKInterfaceGroups and hiding/unhiding when necessary.
See my answer to the exact same question here https://stackoverflow.com/a/28214768/3588917
Will a timer work for you? For example, when a certain time elapsed, you can change the UI of the glance to show a different type of data? When a user taps a glance, you will be able to tell what data is showing in the glance at the time and pass relevant contextual data and redirect them to an appropriate interface controller?
"When the user taps a glance, Apple Watch launches the corresponding WatchKit app. Normally, launching the app displays its main interface controller. If you want to display a different interface controller at launch time, call the updateUserActivity:userInfo: method from your glance interface controller and use it to provide contextual information about what the glance is doing. At launch time, your app can use that contextual data to display a different interface controller."