So, what is really worth mentioning in the transition to the development of watchOS2 - these are the following three points:
- WKInterfacePicker
- Complications
- WCSession
In this article I will briefly talk about each of them.
WKInterfacePicker
WKInterfacePicker is an innovation from Apple, which extends the development capabilities at times. What is it? If to carry out analogs with development under iOS, then it is UIPickerView for hours, however with more flexible functionality. Control is implemented using the Digital Crown (side wheel).
I will not mention all the features, but I will only note what will be important at the initial stages of development. So, the WKInterfacePicker has 2 important parameters: Style and Focus Style. Changing the style (Style), we change the way information is displayed.
')
I'll start right away with an example. Contrary to the hipster ideas, I will provide the code written in the good old classics - Objective-C.
Add to our InterfaceController outlet for a picker:
@property (unsafe_unretained, nonatomic) IBOutlet WKInterfacePicker *picker;
Set the picker style to List mode.

And copy-paste code:
- (void)willActivate {
In the first case (List) we can display the text in the form we are used to.

By setting the Stack item, we get a set of pictures with pre-installed animation.


By selecting the Sequence item, we can also control the set image, but without animation, which allows using this method to control properties such as volume, sensitivity, alpha channel depth, etc.


However, it is worth mentioning something important: before you start drawing art, you should create about a hundred storyboards with a resolution of x2 (x3). This will ensure smooth scrolling and expand the range of variable values.
By the way, we can track the current index by creating an action (non-standard way, I personally expected the delegate method or something like the controller interface method for the
table didSelectRowAtIndex
).
We pull the picker into the header and prescribe the name of the method, like this:
- (IBAction)pickerDidSelectValue:(NSInteger)value;
Next, we control the resulting value as desired.
By changing the Focus Style parameter, we can set or turn off the visibility of piker borders. However, at the moment there is no possibility to change any focus properties (in the active state of the picker, the focus is green with default roundings).






Overall, the WKinterfacePicker is a powerful tool that opens up tremendous opportunities for the developer.
Complications
In essence, Complications are the small elements that we see when opening a Modular watch face. The literal translation of the word complications is a complication. Accident? I do not think. After all, the shell for this seemingly simple functional is the whole ClockKit framework. When you first view the content, you can be horrified, although everything is not so sad. Let us analyze, as briefly as possible, since this topic is a separate article.
When creating a new project, we are offered the possibility of connecting “complications”. When the check mark is set for our project, the ComplicationController class is added.


The CLKComplicationDataSource protocol is connected to the header of this class. In the implementation of the pre-installed 9 methods. The first 4 actually set the conditions for supporting Complications in Time Travel mode. We are interested in a different method.
- (void)getCurrentTimelineEntryForComplication:(CLKComplication *)complication withHandler:(void(^)(CLKComplicationTimelineEntry * __nullable))handler { }
He is key here. In it we set the "entry point" of our complication with the specified parameters and date. It looks like this: first, we create an empty object of the CLKComplicationTimelineEntry class.
CLKComplicationTimelineEntry* entry = nil;
Then we dance on what type of complication we want to use. For example, take Modular Small and put the picture there.
if (complication.family == CLKComplicationFamilyModularSmall) { CLKComplicationTemplateModularSmallSimpleImage* image = [[CLKComplicationTemplateModularSmallSimpleImage alloc] init]; [image setImageProvider: [CLKImageProvider imageProviderWithOnePieceImage:[UIImage imageNamed:@"cat"]]];
Then we customize the selected Modular watch face and get a funny cat from our test application. Profit.



In similar schemes, you can install pictures and texts of different formats (single, in blocks and columns). In general, it is very convenient and makes life easier for the user, for whom it is important to quickly find out the latest information from your application.
WCSession
A new era of synchronization between the iPhone and Apple Watch has arrived. If you caught the time of Apple's “crutch”, called openParentApplication, or used the AppGroup along with the
wormhole , then it's time to forget about them. Now there are 3 ways to transfer information between devices using the "session":
- Application context
- Transferring Files and Data
- Sending Messages
The first thing to do is connect the WatchConnectivity framework. It provides the ability to communicate between devices.
#import <WatchConnectivity/WatchConnectivity.h>
Pre-connect the WCSessionDelegate protocol in the classes between which we will make the transfer. Next, we check session support. If all is well, then turn it on. In the future, all calls to the session are made via [WCSession defaultSession].
if ([WCSession isSupported]) { WCSession *session = [WCSession defaultSession]; session.delegate = self; [session activateSession]; } NSDictionary *dict = @{@"key": @", "}; [[WCSession defaultSession] updateApplicationContext:dict error:nil];
If you need constant synchronization between the phone and the clock, then this is the best way. The following option allows you to transfer information using 2 methods (sequentially, starting with the latest changes before the loss of synchronization between devices):
transferUserInfo: (send to NSDictionary)
transferFile: metadata: (sending file by URL + NSDictionary with metadata)
Similarly:
session didReceiveUserInfo: (get NSDictionary)
session didReceiveFile: (we get WCSessionFile with a link to the file and a library with metadata)
Well, the last option will look at a specific example. As already mentioned, we import the WatchConnectivity framework in the standard ViewController and InterfaceController classes. We connect the WatchConnectivity protocol:
@interface ViewController : UIViewController <WCSessionDelegate> @interface InterfaceController : WKInterfaceController <WCSessionDelegate>
In the implementation of the prescribed:
- (void)viewDidLoad { [super viewDidLoad]; if ([WCSession isSupported]) { WCSession *session = [WCSession defaultSession]; session.delegate = self; [session activateSession]; } } - (void)awakeWithContext:(id)context { [super awakeWithContext:context]; if ([WCSession isSupported]) { WCSession *session = [WCSession defaultSession]; session.delegate = self; [session activateSession]; } }
We will display information on the clock when clicking a button on the iPhone. To do this, add a button to the Main.storyboard and drag IBAction:
- (IBAction)buttonClicked:(id)sender;
.
In the Interface.storyboard we add a label and drag Outlet:
@property (unsafe_unretained, nonatomic) IBOutlet WKInterfaceLabel *infoHere;
By pressing the button, we create a random number and transfer it to the clock using the NSDictionary:
- (IBAction)buttonClicked:(id)sender { NSString* randomValue = [NSString stringWithFormat:@"%u", (arc4random() % 10000) ]; [[WCSession defaultSession] sendMessage:@{@"key": randomValue]} replyHandler:^(NSDictionary<NSString *,id> * _Nonnull replyMessage) { } errorHandler:^(NSError * _Nonnull error) { }];
On the reverse side we write:
-(void)session:(WCSession *)session didReceiveMessage:(NSDictionary<NSString *,id> *)message replyHandler:(void (^)(NSDictionary<NSString *,id> * _Nonnull))replyHandler { dispatch_async(dispatch_get_main_queue(), ^{ NSString* string = [message objectForKey:@"key"]; [self.label setText:string]; }); }
There is one important point. We update the UI in the main thread asynchronously, otherwise there will be display problems. To understand the reasons, I advise you to read articles and documentation about multithreading.
To summarize I have listed a few innovations that I personally consider to be the most significant with the arrival of OS2. Undoubtedly, it is possible to tell more about each of them, and it is quite voluminous, but each of us needs basic knowledge to master a particular area. So let this article be the point of reference for programmers who decide to associate themselves with the development of watchOS.