Since mid-January I have been working full time on the Apple Watch part of the WhereNotes App. I was also lucky enough to be invited to the Apple Watch Lab in Cupertino. During the past three and a half months I have collected a lot of tips and tricks, and I have covered most of them in this post. I hope these tips can help you in your Apple Watch development. You may be familiar with methods like applicationWillEnterForeground: and applicationDidEnterBackground:. They are called before the corresponding notifications (UIApplicationWillEnterForegroundNotification and UIApplicationDidEnterBackgroundNotification). The equivalent (lesser known) WatchKit NSExtensionContext notifications are as follows: NSExtensionHostWillEnterForegroundNotification? NSExtensionHostDidEnterBackgroundNotification? NSExtensionHostWillResignActiveNotification? NSExtensionHostDidBecomeActiveNotification My experience, as that of most members of the Apple developer community, is that testing with a Watch on a charger results in a much better and more reliable debugging experience. On iOS, you can update interface elements at any time, but on WatchKit, you can only update elements in the currently active, visible view controller. Updates can't be performed safely until the didDeactivate method is called. (Note that you can't update interface elements in this method.) This means that if you plan to update a view controller that is currently hidden (for example, you are viewing a top-most modal controller), you will need to implement the current controller's willActivate method, which will be called when the modal controller is dismissed. In addition to the assets included in your Watch app bundle, each app is allowed to cache only 5MB of high-speed images, which are imported and managed by your extension using methods in WKInterfaceDevice. Sending images from your extension to the watch takes time and battery life, so if you need to reuse an image (even if it’s just once), it’s worth caching it. If you send an image using addCachedImage:name:, it will automatically be encoded as a PNG and sent to the cache. This doesn’t matter whether PNG is the best format (but it’s the safest). If your images can be rendered as JPGs, I strongly recommend using addCachedImageWithData:name: instead. By encoding your images as JPGs and experimenting with the image quality settings, not only will the images be transferred faster, but you’ll also have more cache space to store more images. As suggested before, you can cache images in the background process (according to an Apple employee in the developer community). I use this technique in my Watch app to cache images in advance. If you use the image cache mentioned above, there is no built-in way to determine the oldest used image to be deleted. If your app manages many images, you will want to encapsulate the cache manager. To test notifications on your Apple Watch, turn off Wrist Detection in the General settings of the app you paired your Apple Watch with. To force quit an app, press and hold the side button, then press and hold it again after a while (note that force quitting your app will not force quit your extension). Minimize the processing work in willActivate to reduce loading waiting time. Consider whether users should open your Watch app before using your iPhone app and the consistency of the design. App review will reveal these situations. Remember that your Watch app runs as an extension. Your Watch app will have stricter memory limits than your iPhone app. If you’re working with a lot of images, you’ll be better off doing it on the iPhone app (using openParentApplication:reply:). Also note that the simulator doesn’t enforce these memory limits, so you must test on a real device. To find out if your app is paired with the Watch, set a BOOL value in NSUserDefaults shared by the Watch app (using the shared app group) that your iPhone app can access. To sync data between the iPhone and the Watch, you can either call your iPhone app to perform all data updates (using openParentApplication:reply:), or use Darwin notifications to send events between the extension and the iPhone app. Darwin notifications do not support data loading, so if you want to transfer data via notifications, check out the very useful MMWormhole project. In addition to using timers to update and refresh UI elements, you can also use KVO if your data source supports it. This is the approach I use in my Watch app. With this approach, UI elements are updated only when they change, reducing communication overhead and saving battery power. If you need to keep track of your interface controller, consider passing a reference to self in awakeWithContext: to establish a relationship. I've used this pattern extensively in my apps through my JBInterfaceController subclass. Using techniques like this allows you to work with the delegate pattern as you would with a controller. Also, think of your controller more like a UIViewController. The WatchKit extension is a foreground extension, so if you need to obtain Core Location authorization permissions, you only need to request them when authorization is required. Unless your scenario requires it, carefully consider whether you need "online updates" that sync between the Watch and iPhone immediately. Users don't usually use both devices at the same time, so simply updating the data the next time the Watch or iPhone app is activated can avoid a lot of synchronization logic. Unfortunately, looking at the watch and iPhone simulator screens next to each other, it's tempting to build complex synchronization logic. Maybe I did, but I didn't tell you. When you can't create and control view controllers programmatically, you can be smart about how you hide and show view elements. This can become a common WatchKit practice, for example, to have a full-page label that can be displayed if there is an important message to be presented. Or, if you have two layouts that you need to select programmatically, you can include them in the top-level group and let them hide and show as needed. Keep in mind that every screen touch and interface update requires back-and-forth communication between the Watch and the iPhone. WatchKit interface elements are write-only (they usually have setter methods as well), which requires manual tracking of values that you’ve already set and that you don’t want to set again. WatchKit tries to merge values and send only the latest value on each run loop, but you can also participate and track your own values. While there is no built-in activity indicator control, you can display a sequence of animated images while a long process is in progress (such as image streaming or downloading). Update 5/3/2015: I just published the JBWatchActivityIndicator project on GitHub, which makes it easier to create activity indicator image sequences. It also includes some Apple-style pre-rendered sequences. Be sure to download and review the Apple Watch Design Resources. In addition to helpful color and size recommendations, they also include high-quality images for marketing screenshots. While I’m on the subject, your app screenshot submission without a bezel image is worthless. Many developers have expressed frustration with images that appear correct on the simulator but not on the actual watch. In fact, this is the reason many apps are rejected. This problem has to do with file naming and missing files. The safest solution is to include all images in the assets library of the Watch app (not the extension). This is what I do in my Watch app. I recommend you do the same. While being able to load your iPhone app to the foreground from the Watch is a very common requirement, it is not possible programmatically (even if there is a way to run it on the simulator), so consider using Handoff instead. If you need to pass information between two view controllers, but you can't do it with awakeWithContext:, consider sending NSNotifications. They work well in extensions. Otherwise, clone my JBInterfaceController subclass remotely and use the proxy pattern. Local notifications require the soundName property to be set to generate haptic feedback and ringtones. The simulator is a good start, but testing your app on real hardware devices is key. |
>>: What computer technology skills do programmers have that would amaze non-programmers?
With the development of the Internet, it can even...
The job of an information flow advertising optimi...
1. Polarization <p class="MsoListParagraph" st...
Course Description This course is the entry-level...
Recently, a kid sent me a video: a sports car ent...
The company's new brand is about to enter the...
Same problem: Where can I check the Toutiao Index...
As a traditional household appliance, television ...
On May 31, 2021, the latest issue of the "Ch...
Compiled by Zhou Shuyi and Wang Xiang People who ...
Source: China Science and Technology Museum The c...
Today is World Earth Day. Our planet has a variet...
Reviewer: Luo Huiqian, Associate Researcher, Inst...
"Wealthy and willful" and "Interne...
1. Weibo Fans Pass Billing Method 1. Real-time bi...