Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Timob 18854 : Add Delegate & Reply for openParentApplication to Titanium #6803

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
61 changes: 60 additions & 1 deletion apidoc/Titanium/App/iOS/iOS.yml
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,35 @@ methods:
osver: {ios: {min: "7.0"}}
since: "3.2.0"

- name: sendWatchExtensionReply
summary: |
Marks the end of an openParentApplication:reply execution by a WatchKit extension.
Available only on iOS 8.2 and later.
description: |
This method must be called after your Titaium application has finished processing the `watchkitextensionrequest` event. Optional
information can be provided in the userInfo argument will be provided back to the WatchKit extension as part of the reply method.
If no userInfo is provide nil will be sent to the WatchKit extension to during the reply callback.

This method should be used as part of the `watchkitextensionrequest` event as shown below.

Ti.App.iOS.addEventListener("watchkitextensionrequest",function(e){
var replyContent = {foo:"bar"};
Ti.App.iOS.sendWatchExtensionReply(e.handlerId,replyContent);
});

parameters:
- name: handlerId
summary: |
Unique string identifer for the event (`watchkitextensionrequest`)
that initiated from the WatchKit extension calling the openParentApplication:reply method.
type: String
- name: userInfo
summary: |
Custom data object which will be passed in the reply method to your WatchKit extension.
type: Dictionary
osver: {ios: {min: "8.2"}}
since: "4.1.0"

properties:
- name: EVENT_ACCESSIBILITY_LAYOUT_CHANGED
summary: Convenience constant for system event "accessibilitylayoutchanged".
Expand Down Expand Up @@ -568,7 +597,6 @@ events:
osver: {ios: {min: "7.0"}}
since: "3.2.0"


- name: usernotificationsettings
summary: |
Fired when the user notification settings are registered (available for iOS 8 and later).
Expand All @@ -584,6 +612,37 @@ events:
osver: {ios: {min: "8.0"}}
since: "3.4.0"

- name: watchkitextensionrequest
summary: Fired when openParentApplication:reply is called from a WatchKit extension. Available only on iOS 8.2 and later.
description: |
Add this event if your Titanium application if you are using a WatchKit extension. When your WatchKit extension uses the openParentApplication:reply
method your Titanium application will be opened in the background and provides your Titanium app the information from the extension. When this
event is fired you must provide a reply by calling the [sendWatchExtensionReply](Titanium.App.iOS.sendWatchExtensionReply) method with
the `handlerID` parameter from this event.

The event returns the dictionary containing the `handlerID` property, which is a unique handler ID for the
current event and the `userInfo` property, containing the dictionary passed from the WatchKit extension. The `handlerID` identifier
must be passed as the an argument to the [sendWatchExtensionReply](Titanium.App.iOS.sendWatchExtensionReply) method.

Ti.App.iOS.addEventListener("watchkitextensionrequest",function(e){
var replyContent = {foo:"bar"};
Ti.App.iOS.sendWatchExtensionReply(e.handlerId,replyContent);
});

properties:
- name: handlerId
summary: |
Unique string identifer for the `watchkitextensionrequest` event. This identifier should be passed an argument
to the [sendWatchExtensionReply](Titanium.App.iOS.sendWatchExtensionReply) method.
type: String
- name: userInfo
summary: |
The payload passed to the openParentApplication:reply method from the WatchKit extension.
type: Dictionary
platforms: [iphone, ipad]
osver: {ios: {min: "8.2"}}
since: '4.1.0'

---
name: NotificationParams
summary: |
Expand Down
3 changes: 2 additions & 1 deletion iphone/Classes/TiApp.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ TI_INLINE void waitForMemoryPanicCleared() //WARNING: This must never be run o
id remoteNotificationDelegate;
NSDictionary* remoteNotification;
NSMutableDictionary* pendingCompletionHandlers;
NSMutableDictionary* pendingReplyHandlers;
NSMutableDictionary* backgroundTransferCompletionHandlers;
BOOL appBooted;

Expand Down Expand Up @@ -209,6 +210,6 @@ TI_INLINE void waitForMemoryPanicCleared() //WARNING: This must never be run o
-(void)stopBackgroundService:(TiProxy*)proxy;
-(void)completionHandler:(id)key withResult:(int)result;
-(void)completionHandlerForBackgroundTransfer:(id)key;

-(void)watchKitExtensionRequestHandler:(id)key withUserInfo:(NSDictionary*)userInfo;
@end

42 changes: 42 additions & 0 deletions iphone/Classes/TiApp.m
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,48 @@ - (void) application:(UIApplication *)application handleActionWithIdentifier:(NS
completionHandler();
}


#pragma mark Apple Watchkit handleWatchKitExtensionRequest
- (void)application:(UIApplication *)application
handleWatchKitExtensionRequest:(NSDictionary *)userInfo
reply:(void (^)(NSDictionary *replyInfo))reply
{

// Generate unique key with timestamp.
id key = [NSString stringWithFormat:@"watchkit-reply-%f",[[NSDate date] timeIntervalSince1970]];

if (pendingReplyHandlers == nil) {
pendingReplyHandlers = [[NSMutableDictionary alloc] init];
}

[pendingReplyHandlers setObject:[[reply copy] autorelease ]forKey:key];

NSMutableDictionary* dic = [[[NSMutableDictionary alloc] init] autorelease];
[dic setObject:key forKey:@"handlerId"];
if(userInfo!=nil){
[dic setObject:userInfo forKey:@"userInfo"];
}

[[NSNotificationCenter defaultCenter] postNotificationName:KTiWatchKitExtensionRequest object:self userInfo:dic];
}

-(void)watchKitExtensionRequestHandler:(id)key withUserInfo:(NSDictionary*)userInfo
{
if (pendingReplyHandlers == nil) {
DebugLog(@"[ERROR] No WatchKitExtensionRequest have been recieved yet");
return;
}

if ([pendingReplyHandlers objectForKey:key]) {
void(^replyBlock)(NSDictionary *input);
replyBlock = [pendingReplyHandlers objectForKey:key];
replyBlock(userInfo);
[pendingReplyHandlers removeObjectForKey:key];
} else {
DebugLog(@"[ERROR] The specified WatchKitExtensionRequest Handler with ID: %@ has already expired or removed from the system", key);
}
}

#pragma mark -

#pragma mark Helper Methods
Expand Down
40 changes: 40 additions & 0 deletions iphone/Classes/TiAppiOSProxy.m
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ -(void)_listenerAdded:(NSString*)type count:(int)count
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector
(didRegisterUserNotificationSettingsNotification:) name:kTiUserNotificationSettingsNotification object:nil];
}
if ((count == 1) && [type isEqual:@"watchkitextensionrequest"]) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(didReceiveWatchExtensionRequestNotification:) name:KTiWatchKitExtensionRequest object:nil];
}
}

}
Expand Down Expand Up @@ -127,6 +131,9 @@ -(void)_listenerRemoved:(NSString*)type count:(int)count
if ((count == 1) && [type isEqual:@"usernotificationsetting"]) {
[[NSNotificationCenter defaultCenter] removeObserver:self name:kTiUserNotificationSettingsNotification object:nil];
}
if ((count == 1) && [type isEqual:@"watchkitextensionrequest"]) {
[[NSNotificationCenter defaultCenter] removeObserver:self name:KTiWatchKitExtensionRequest object:nil];
}
}
}

Expand Down Expand Up @@ -544,6 +551,39 @@ -(void)didRegisterUserNotificationSettingsNotification:(NSNotification*)notifica
withObject:[self formatUserNotificationSettings:(UIUserNotificationSettings*)[notificationSettings object]]];
}

#pragma mark Apple Watchkit notifications

-(void)didReceiveWatchExtensionRequestNotification:(NSNotification*)notif
{
[self fireEvent:@"watchkitextensionrequest" withObject:[notif userInfo]];
}

#pragma mark Apple Watchkit handleWatchKitExtensionRequest reply

-(void)sendWatchExtensionReply:(id)args
{
if(![TiUtils isIOS8OrGreater]) {
return;
}

enum Args {
kArgKey = 0,
kArgCount,
kArgUserInfo = kArgCount
};

ENSURE_TYPE(args,NSArray);
ENSURE_ARG_COUNT(args, kArgCount);

NSString *key = [TiUtils stringValue:[args objectAtIndex:kArgKey]];

if([args count] > 1){
[[TiApp app] watchKitExtensionRequestHandler:key withUserInfo:[args objectAtIndex:kArgUserInfo]];
}else{
[[TiApp app] watchKitExtensionRequestHandler:key withUserInfo:nil];
}
}

-(void)setMinimumBackgroundFetchInterval:(id)value
{
ENSURE_TYPE(value, NSNumber);
Expand Down
1 change: 1 addition & 0 deletions iphone/Classes/TiBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,7 @@ extern NSString * const kTiURLSessionCompleted;
extern NSString * const kTiURLSessionEventsCompleted;
extern NSString * const kTiURLDowloadProgress;
extern NSString * const kTiURLUploadProgress;
extern NSString * const KTiWatchKitExtensionRequest;

extern NSString* const kTiBehaviorSize;
extern NSString* const kTiBehaviorFill;
Expand Down
1 change: 1 addition & 0 deletions iphone/Classes/TiBase.m
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ void TiLogMessage(NSString* str, ...) {
NSString * const kTiLocalNotificationAction = @"TiLocalNotificationAction";
NSString * const kTiRemoteNotificationAction = @"TiRemoteNotificationAction";
NSString * const kTiUserNotificationSettingsNotification = @"TiUserNotificationSettingsNotification";
NSString * const KTiWatchKitExtensionRequest = @"TiWatchKitExtensionRequest";

NSString* const kTiBehaviorSize = @"SIZE";
NSString* const kTiBehaviorFill = @"FILL";
Expand Down