objc2-watch-connectivity 0.3.2

Bindings to the WatchConnectivity framework
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
//! This file has been automatically generated by `objc2`'s `header-translator`.
//! DO NOT EDIT
use core::ffi::*;
use core::ptr::NonNull;
use objc2::__framework_prelude::*;
use objc2_foundation::*;

use crate::*;

/// [Apple's documentation](https://developer.apple.com/documentation/watchconnectivity/wcsessionactivationstate?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct WCSessionActivationState(pub NSInteger);
impl WCSessionActivationState {
    #[doc(alias = "WCSessionActivationStateNotActivated")]
    pub const NotActivated: Self = Self(0);
    #[doc(alias = "WCSessionActivationStateInactive")]
    pub const Inactive: Self = Self(1);
    #[doc(alias = "WCSessionActivationStateActivated")]
    pub const Activated: Self = Self(2);
}

unsafe impl Encode for WCSessionActivationState {
    const ENCODING: Encoding = NSInteger::ENCODING;
}

unsafe impl RefEncode for WCSessionActivationState {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

extern_class!(
    /// -------------------------------- WCSession --------------------------------
    /// The default session is used to communicate between two counterpart apps
    /// (i.e. iOS app and its native WatchKit extension). The session provides
    /// methods for sending, receiving, and tracking state.
    ///
    /// On start up an app should set a delegate on the default session and call
    /// activate. This will allow the system to populate the state properties and
    /// deliver any outstanding background transfers.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/watchconnectivity/wcsession?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct WCSession;
);

extern_conformance!(
    unsafe impl NSObjectProtocol for WCSession {}
);

impl WCSession {
    extern_methods!(
        /// Check if session is supported on this iOS device. Session is always available on WatchOS
        #[unsafe(method(isSupported))]
        #[unsafe(method_family = none)]
        pub unsafe fn isSupported() -> bool;

        /// Use the default session for all transferring of content and state monitoring.
        #[unsafe(method(defaultSession))]
        #[unsafe(method_family = none)]
        pub unsafe fn defaultSession() -> Retained<WCSession>;

        /// Use the default session instead.
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;

        /// A delegate must exist before the session will allow sends.
        #[unsafe(method(delegate))]
        #[unsafe(method_family = none)]
        pub unsafe fn delegate(&self) -> Option<Retained<ProtocolObject<dyn WCSessionDelegate>>>;

        /// Setter for [`delegate`][Self::delegate].
        ///
        /// This is a [weak property][objc2::topics::weak_property].
        #[unsafe(method(setDelegate:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setDelegate(&self, delegate: Option<&ProtocolObject<dyn WCSessionDelegate>>);

        /// The default session must be activated on startup before the session's properties contain correct values and will begin receiving delegate callbacks. Calling activate without a delegate set is undefined. If the WCSessionDelegate session:activationDidCompleteWithState:error: is implemented this method becomes an asynchronous call.
        #[unsafe(method(activateSession))]
        #[unsafe(method_family = none)]
        pub unsafe fn activateSession(&self);

        /// The state of the current session
        #[unsafe(method(activationState))]
        #[unsafe(method_family = none)]
        pub unsafe fn activationState(&self) -> WCSessionActivationState;

        /// Whether or not there is more content for the session to deliver
        #[unsafe(method(hasContentPending))]
        #[unsafe(method_family = none)]
        pub unsafe fn hasContentPending(&self) -> bool;

        /// Check if iOS device is paired to a watch
        #[unsafe(method(isPaired))]
        #[unsafe(method_family = none)]
        pub unsafe fn isPaired(&self) -> bool;

        /// Check if the user has the Watch app installed
        #[unsafe(method(isWatchAppInstalled))]
        #[unsafe(method_family = none)]
        pub unsafe fn isWatchAppInstalled(&self) -> bool;

        /// Check if the user has the Watch app's complication enabled
        #[unsafe(method(isComplicationEnabled))]
        #[unsafe(method_family = none)]
        pub unsafe fn isComplicationEnabled(&self) -> bool;

        /// The number of calls remaining to transferCurrentComplicationUserInfo: before the system starts transferring the complicationUserInfo as regular userInfos. If this is 0, the complicationUserInfo will be transferred as regular userInfos. Count will be 0 whenever the complication is not enabled
        #[unsafe(method(remainingComplicationUserInfoTransfers))]
        #[unsafe(method_family = none)]
        pub unsafe fn remainingComplicationUserInfoTransfers(&self) -> NSUInteger;

        /// Use this directory to persist any data specific to the selected Watch. The location of the URL will change when the selected Watch changes. This directory will be deleted upon next launch if the watch app is uninstalled for the selected Watch, or that Watch is unpaired. If the watch app is not installed for the selected Watch the value will be nil.
        #[unsafe(method(watchDirectoryURL))]
        #[unsafe(method_family = none)]
        pub unsafe fn watchDirectoryURL(&self) -> Option<Retained<NSURL>>;

        /// Check if the companion app is installed on the paired iPhone. This only applies to Watch apps that can run independently.
        #[unsafe(method(isCompanionAppInstalled))]
        #[unsafe(method_family = none)]
        pub unsafe fn isCompanionAppInstalled(&self) -> bool;

        /// The counterpart app must be reachable for a send message to succeed.
        #[unsafe(method(isReachable))]
        #[unsafe(method_family = none)]
        pub unsafe fn isReachable(&self) -> bool;

        /// Reachability in the Watch app requires the paired iOS device to have been unlocked at least once after reboot. This property can be used to determine if the iOS device needs to be unlocked. If the reachable property is set to NO it may be because the iOS device has rebooted and needs to be unlocked. If this is the case, the Watch can show a prompt to the user suggesting they unlock their paired iOS device.
        #[unsafe(method(iOSDeviceNeedsUnlockAfterRebootForReachability))]
        #[unsafe(method_family = none)]
        pub unsafe fn iOSDeviceNeedsUnlockAfterRebootForReachability(&self) -> bool;

        #[cfg(feature = "block2")]
        /// Clients can use this method to send messages to the counterpart app. Clients wishing to receive a reply to a particular message should pass in a replyHandler block. If the message cannot be sent or if the reply could not be received, the errorHandler block will be invoked with an error. If both a replyHandler and an errorHandler are specified, then exactly one of them will be invoked. Messages can only be sent while the sending app is running. If the sending app exits before the message is dispatched the send will fail. If the counterpart app is not running the counterpart app will be launched upon receiving the message (iOS counterpart app only). The message dictionary can only accept the property list types.
        ///
        /// # Safety
        ///
        /// `message` generic should be of the correct type.
        #[unsafe(method(sendMessage:replyHandler:errorHandler:))]
        #[unsafe(method_family = none)]
        pub unsafe fn sendMessage_replyHandler_errorHandler(
            &self,
            message: &NSDictionary<NSString, AnyObject>,
            reply_handler: Option<
                &block2::DynBlock<dyn Fn(NonNull<NSDictionary<NSString, AnyObject>>)>,
            >,
            error_handler: Option<&block2::DynBlock<dyn Fn(NonNull<NSError>)>>,
        );

        #[cfg(feature = "block2")]
        /// Clients can use this method to send message data. All the policies of send message apply to send message data. Send message data is meant for clients that have an existing transfer format and do not need the convenience of the send message dictionary.
        #[unsafe(method(sendMessageData:replyHandler:errorHandler:))]
        #[unsafe(method_family = none)]
        pub unsafe fn sendMessageData_replyHandler_errorHandler(
            &self,
            data: &NSData,
            reply_handler: Option<&block2::DynBlock<dyn Fn(NonNull<NSData>)>>,
            error_handler: Option<&block2::DynBlock<dyn Fn(NonNull<NSError>)>>,
        );

        /// Setting the applicationContext is a way to transfer the latest state of an app. After updating the applicationContext, the system initiates the data transfer at an appropriate time, which can occur after the app exits. The counterpart app will receive a delegate callback on next launch if the applicationContext has successfully arrived. If there is no app context, it should be updated with an empty dictionary. The applicationContext dictionary can only accept the property list types.
        #[unsafe(method(applicationContext))]
        #[unsafe(method_family = none)]
        pub unsafe fn applicationContext(&self) -> Retained<NSDictionary<NSString, AnyObject>>;

        /// # Safety
        ///
        /// `application_context` generic should be of the correct type.
        #[unsafe(method(updateApplicationContext:error:_))]
        #[unsafe(method_family = none)]
        pub unsafe fn updateApplicationContext_error(
            &self,
            application_context: &NSDictionary<NSString, AnyObject>,
        ) -> Result<(), Retained<NSError>>;

        /// Stores the most recently received applicationContext from the counterpart app.
        #[unsafe(method(receivedApplicationContext))]
        #[unsafe(method_family = none)]
        pub unsafe fn receivedApplicationContext(
            &self,
        ) -> Retained<NSDictionary<NSString, AnyObject>>;

        #[cfg(feature = "WCSessionUserInfoTransfer")]
        /// The system will enqueue the user info dictionary and transfer it to the counterpart app at an opportune time. The transfer of user info will continue after the sending app has exited. The counterpart app will receive a delegate callback on next launch if the file has successfully arrived. The userInfo dictionary can only accept the property list types.
        ///
        /// # Safety
        ///
        /// `user_info` generic should be of the correct type.
        #[unsafe(method(transferUserInfo:))]
        #[unsafe(method_family = none)]
        pub unsafe fn transferUserInfo(
            &self,
            user_info: &NSDictionary<NSString, AnyObject>,
        ) -> Retained<WCSessionUserInfoTransfer>;

        #[cfg(feature = "WCSessionUserInfoTransfer")]
        /// Enqueues a user info dictionary containing the most current information for an enabled complication. If the app's complication is enabled the system will try to transfer this user info immediately. Once a current complication user info is received the system will launch the Watch App Extension in the background and allow it to update the complication content. If the current user info cannot be transferred (i.e. devices disconnected, out of background launch budget, etc.) it will wait in the outstandingUserInfoTransfers queue until next opportune time. There can only be one current complication user info in the outstandingUserInfoTransfers queue. If a current complication user info is outstanding (waiting to transfer) and -transferCurrentComplicationUserInfo: is called again with new user info, the new user info will be tagged as current and the previously current user info will be untagged. The previous user info will however stay in the queue of outstanding transfers.
        ///
        /// # Safety
        ///
        /// `user_info` generic should be of the correct type.
        #[unsafe(method(transferCurrentComplicationUserInfo:))]
        #[unsafe(method_family = none)]
        pub unsafe fn transferCurrentComplicationUserInfo(
            &self,
            user_info: &NSDictionary<NSString, AnyObject>,
        ) -> Retained<WCSessionUserInfoTransfer>;

        #[cfg(feature = "WCSessionUserInfoTransfer")]
        /// Returns an array of user info transfers that are still transferring (i.e. have not been cancelled, failed, or been received by the counterpart app).
        #[unsafe(method(outstandingUserInfoTransfers))]
        #[unsafe(method_family = none)]
        pub unsafe fn outstandingUserInfoTransfers(
            &self,
        ) -> Retained<NSArray<WCSessionUserInfoTransfer>>;

        #[cfg(feature = "WCSessionFile")]
        /// The system will enqueue the file and transfer it to the counterpart app at an opportune time. The transfer of a file will continue after the sending app has exited. The counterpart app will receive a delegate callback on next launch if the file has successfully arrived. The metadata dictionary can only accept the property list types.
        ///
        /// # Safety
        ///
        /// `metadata` generic should be of the correct type.
        #[unsafe(method(transferFile:metadata:))]
        #[unsafe(method_family = none)]
        pub unsafe fn transferFile_metadata(
            &self,
            file: &NSURL,
            metadata: Option<&NSDictionary<NSString, AnyObject>>,
        ) -> Retained<WCSessionFileTransfer>;

        #[cfg(feature = "WCSessionFile")]
        /// Returns an array of file transfers that are still transferring (i.e. have not been cancelled, failed, or been received by the counterpart app).
        #[unsafe(method(outstandingFileTransfers))]
        #[unsafe(method_family = none)]
        pub unsafe fn outstandingFileTransfers(&self) -> Retained<NSArray<WCSessionFileTransfer>>;
    );
}

/// Methods declared on superclass `NSObject`.
impl WCSession {
    extern_methods!(
        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub unsafe fn new() -> Retained<Self>;
    );
}

extern_protocol!(
    /// ----------------------------- WCSessionDelegate -----------------------------
    /// The session calls the delegate methods when content is received and session
    /// state changes. All delegate methods will be called on the same queue. The
    /// delegate queue is a non-main serial queue. It is the client's responsibility
    /// to dispatch to another queue if neccessary.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/watchconnectivity/wcsessiondelegate?language=objc)
    pub unsafe trait WCSessionDelegate: NSObjectProtocol {
        /// Called when the session has completed activation. If session state is WCSessionActivationStateNotActivated there will be an error with more details.
        #[unsafe(method(session:activationDidCompleteWithState:error:))]
        #[unsafe(method_family = none)]
        unsafe fn session_activationDidCompleteWithState_error(
            &self,
            session: &WCSession,
            activation_state: WCSessionActivationState,
            error: Option<&NSError>,
        );

        /// Called when the session can no longer be used to modify or add any new transfers and, all interactive messages will be cancelled, but delegate callbacks for background transfers can still occur. This will happen when the selected watch is being changed.
        #[unsafe(method(sessionDidBecomeInactive:))]
        #[unsafe(method_family = none)]
        unsafe fn sessionDidBecomeInactive(&self, session: &WCSession);

        /// Called when all delegate callbacks for the previously selected watch has occurred. The session can be re-activated for the now selected watch using activateSession.
        #[unsafe(method(sessionDidDeactivate:))]
        #[unsafe(method_family = none)]
        unsafe fn sessionDidDeactivate(&self, session: &WCSession);

        /// Called when any of the Watch state properties change.
        #[optional]
        #[unsafe(method(sessionWatchStateDidChange:))]
        #[unsafe(method_family = none)]
        unsafe fn sessionWatchStateDidChange(&self, session: &WCSession);

        /// Called when the installed state of the Companion app changes.
        #[optional]
        #[unsafe(method(sessionCompanionAppInstalledDidChange:))]
        #[unsafe(method_family = none)]
        unsafe fn sessionCompanionAppInstalledDidChange(&self, session: &WCSession);

        /// Called when the reachable state of the counterpart app changes. The receiver should check the reachable property on receiving this delegate callback.
        #[optional]
        #[unsafe(method(sessionReachabilityDidChange:))]
        #[unsafe(method_family = none)]
        unsafe fn sessionReachabilityDidChange(&self, session: &WCSession);

        /// Called on the delegate of the receiver. Will be called on startup if the incoming message caused the receiver to launch.
        ///
        /// # Safety
        ///
        /// `message` generic should be of the correct type.
        #[optional]
        #[unsafe(method(session:didReceiveMessage:))]
        #[unsafe(method_family = none)]
        unsafe fn session_didReceiveMessage(
            &self,
            session: &WCSession,
            message: &NSDictionary<NSString, AnyObject>,
        );

        #[cfg(feature = "block2")]
        /// Called on the delegate of the receiver when the sender sends a message that expects a reply. Will be called on startup if the incoming message caused the receiver to launch.
        ///
        /// # Safety
        ///
        /// `message` generic should be of the correct type.
        #[optional]
        #[unsafe(method(session:didReceiveMessage:replyHandler:))]
        #[unsafe(method_family = none)]
        unsafe fn session_didReceiveMessage_replyHandler(
            &self,
            session: &WCSession,
            message: &NSDictionary<NSString, AnyObject>,
            reply_handler: &block2::DynBlock<dyn Fn(NonNull<NSDictionary<NSString, AnyObject>>)>,
        );

        /// Called on the delegate of the receiver. Will be called on startup if the incoming message data caused the receiver to launch.
        #[optional]
        #[unsafe(method(session:didReceiveMessageData:))]
        #[unsafe(method_family = none)]
        unsafe fn session_didReceiveMessageData(&self, session: &WCSession, message_data: &NSData);

        #[cfg(feature = "block2")]
        /// Called on the delegate of the receiver when the sender sends message data that expects a reply. Will be called on startup if the incoming message data caused the receiver to launch.
        #[optional]
        #[unsafe(method(session:didReceiveMessageData:replyHandler:))]
        #[unsafe(method_family = none)]
        unsafe fn session_didReceiveMessageData_replyHandler(
            &self,
            session: &WCSession,
            message_data: &NSData,
            reply_handler: &block2::DynBlock<dyn Fn(NonNull<NSData>)>,
        );

        /// Called on the delegate of the receiver. Will be called on startup if an applicationContext is available.
        ///
        /// # Safety
        ///
        /// `application_context` generic should be of the correct type.
        #[optional]
        #[unsafe(method(session:didReceiveApplicationContext:))]
        #[unsafe(method_family = none)]
        unsafe fn session_didReceiveApplicationContext(
            &self,
            session: &WCSession,
            application_context: &NSDictionary<NSString, AnyObject>,
        );

        #[cfg(feature = "WCSessionUserInfoTransfer")]
        /// Called on the sending side after the user info transfer has successfully completed or failed with an error. Will be called on next launch if the sender was not running when the user info finished.
        #[optional]
        #[unsafe(method(session:didFinishUserInfoTransfer:error:))]
        #[unsafe(method_family = none)]
        unsafe fn session_didFinishUserInfoTransfer_error(
            &self,
            session: &WCSession,
            user_info_transfer: &WCSessionUserInfoTransfer,
            error: Option<&NSError>,
        );

        /// Called on the delegate of the receiver. Will be called on startup if the user info finished transferring when the receiver was not running.
        ///
        /// # Safety
        ///
        /// `user_info` generic should be of the correct type.
        #[optional]
        #[unsafe(method(session:didReceiveUserInfo:))]
        #[unsafe(method_family = none)]
        unsafe fn session_didReceiveUserInfo(
            &self,
            session: &WCSession,
            user_info: &NSDictionary<NSString, AnyObject>,
        );

        #[cfg(feature = "WCSessionFile")]
        /// Called on the sending side after the file transfer has successfully completed or failed with an error. Will be called on next launch if the sender was not running when the transfer finished.
        #[optional]
        #[unsafe(method(session:didFinishFileTransfer:error:))]
        #[unsafe(method_family = none)]
        unsafe fn session_didFinishFileTransfer_error(
            &self,
            session: &WCSession,
            file_transfer: &WCSessionFileTransfer,
            error: Option<&NSError>,
        );

        #[cfg(feature = "WCSessionFile")]
        /// Called on the delegate of the receiver. Will be called on startup if the file finished transferring when the receiver was not running. The incoming file will be located in the Documents/Inbox/ folder when being delivered. The receiver must take ownership of the file by moving it to another location. The system will remove any content that has not been moved when this delegate method returns.
        #[optional]
        #[unsafe(method(session:didReceiveFile:))]
        #[unsafe(method_family = none)]
        unsafe fn session_didReceiveFile(&self, session: &WCSession, file: &WCSessionFile);
    }
);