Skip to content

Commit

Permalink
Merge pull request #9744 from hansemannn/TIMOB-25048
Browse files Browse the repository at this point in the history
[TIMOB-25048] iOS: Move ApplicationShortcuts to Ti.UI namespace (parity)
  • Loading branch information
ssjsamir committed Oct 17, 2018
2 parents eba461f + df47730 commit fcbd951
Show file tree
Hide file tree
Showing 8 changed files with 285 additions and 6 deletions.
4 changes: 4 additions & 0 deletions iphone/Classes/TiAppiOSProxy.m
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,11 @@ - (void)didReceiveApplicationShortcutNotification:(NSNotification *)info
{
NSMutableDictionary *event = [[NSMutableDictionary alloc] initWithDictionary:@{
@"title" : [[info userInfo] valueForKey:@"title"],
#ifdef USE_TI_UIAPPLICATIONSHORTCUTS
@"identifier" : [[info userInfo] valueForKey:@"type"]
#else
@"itemtype" : [[info userInfo] valueForKey:@"type"]
#endif
}];

if ([[info userInfo] valueForKey:@"subtitle"] != nil) {
Expand Down
14 changes: 14 additions & 0 deletions iphone/Classes/TiUIApplicationShortcutsProxy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Appcelerator Titanium Mobile
* Copyright (c) 2018 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Apache Public License
* Please see the LICENSE included with this distribution for details.
*/
#import "TiProxy.h"

#if defined(USE_TI_UIIOSAPPLICATIONSHORTCUTS) || defined(USE_TI_UIAPPLICATIONSHORTCUTS)
@interface TiUIApplicationShortcutsProxy : TiProxy {
}

@end
#endif
242 changes: 242 additions & 0 deletions iphone/Classes/TiUIApplicationShortcutsProxy.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
/**
* Appcelerator Titanium Mobile
* Copyright (c) 2018 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Apache Public License
* Please see the LICENSE included with this distribution for details.
*/

#if defined(USE_TI_UIIOSAPPLICATIONSHORTCUTS) || defined(USE_TI_UIAPPLICATIONSHORTCUTS)
#import "TiUIApplicationShortcutsProxy.h"
#import "TiUtils.h"
#ifdef USE_TI_CONTACTS
#import "TiContactsPerson.h"
#endif
#import <CommonCrypto/CommonDigest.h>
#import <ContactsUI/ContactsUI.h>

@implementation TiUIApplicationShortcutsProxy

- (NSString *)apiName
{
return @"Ti.UI.ApplicationShortcuts";
}

- (NSDictionary *)shortcutItemToDictionary:(UIApplicationShortcutItem *)item
{
NSMutableDictionary *dict = [NSMutableDictionary
dictionaryWithObjectsAndKeys:item.type, @"identifier",
nil];

if (item.localizedTitle != nil) {
[dict setObject:item.localizedTitle forKey:@"title"];
}

if (item.localizedSubtitle != nil) {
[dict setObject:item.localizedSubtitle forKey:@"subtitle"];
}

if (item.userInfo != nil) {
[dict setObject:item.userInfo forKey:@"userInfo"];
}

return dict;
}

- (NSArray *)listDynamicShortcuts:(id)unused
{
NSMutableArray *shortcutsToReturn = [NSMutableArray array];
NSArray *shortcuts = [UIApplication sharedApplication].shortcutItems;

for (UIApplicationShortcutItem *item in shortcuts) {
[shortcutsToReturn addObject:[self shortcutItemToDictionary:item]];
}

return shortcutsToReturn;
}

- (void)removeAllDynamicShortcuts:(id)unused
{
[UIApplication sharedApplication].shortcutItems = nil;
}

- (NSArray *)listStaticShortcuts:(id)unused
{
NSMutableArray *shortcutsToReturn = [NSMutableArray array];
NSArray *shortcuts = [NSBundle mainBundle].infoDictionary[@"UIApplicationShortcutItems"];

if (shortcuts == nil || [shortcuts count] == 0) {
return @[];
}

for (id item in shortcuts) {
// We need to map the plist-keys manually for static shortcuts
NSString *type = [item valueForKey:@"UIApplicationShortcutItemType"];
NSString *title = [item valueForKey:@"UIApplicationShortcutItemTitle"];
NSString *subtitle = [item valueForKey:@"UIApplicationShortcutItemSubtitle"];
UIApplicationShortcutIcon *icon = [UIApplicationShortcutIcon iconWithType:[TiUtils intValue:[item valueForKey:@"UIApplicationShortcutItemIconType"]]];
NSDictionary *userInfo = [item valueForKey:@"UIApplicationShortcutItemUserInfo"];

UIApplicationShortcutItem *shortcut = [[[UIApplicationShortcutItem alloc] initWithType:type
localizedTitle:title
localizedSubtitle:subtitle
icon:icon
userInfo:userInfo] autorelease];

[shortcutsToReturn addObject:[self shortcutItemToDictionary:shortcut]];
}

return shortcutsToReturn;
}

- (BOOL)typeExists:(NSString *)type
{
NSArray *shortcuts = [UIApplication sharedApplication].shortcutItems;
for (UIApplicationShortcutItem *item in shortcuts) {
if ([item.type isEqualToString:type]) {
return YES;
}
}

return NO;
}

- (NSNumber *)dynamicShortcutExists:(id)identifier
{
ENSURE_SINGLE_ARG(identifier, NSString);

if ([TiUtils stringValue:identifier] == nil) {
NSLog(@"[ERROR] Ti.UI.ApplicationShortcuts: The \"identifier\" property is required.");
return;
}

return NUMBOOL([self typeExists:[TiUtils stringValue:identifier]]);
}

- (NSDictionary *)getDynamicShortcut:(id)identifier
{
ENSURE_SINGLE_ARG(identifier, NSString);

NSArray *shortcuts = [UIApplication sharedApplication].shortcutItems;
for (UIApplicationShortcutItem *item in shortcuts) {
if ([item.type isEqualToString:[TiUtils stringValue:identifier]]) {
return [self shortcutItemToDictionary:item];
}
}

return nil;
}

- (void)removeDynamicShortcut:(id)identifier
{
ENSURE_SINGLE_ARG(identifier, NSString);

NSString *key = [TiUtils stringValue:identifier];

if (key == nil) {
NSLog(@"[ERROR] The \"identifier\" property is required.");
return;
}

if ([self typeExists:key] == NO) {
return;
}

NSMutableArray *shortcuts = (NSMutableArray *)[UIApplication sharedApplication].shortcutItems;

for (UIApplicationShortcutItem *item in shortcuts) {
if ([item.type isEqualToString:key]) {
[shortcuts removeObject:item];
}
}

[UIApplication sharedApplication].shortcutItems = shortcuts;
}

- (void)addDynamicShortcut:(id)args
{
ENSURE_SINGLE_ARG(args, NSDictionary);

if ([args objectForKey:@"identifier"] == nil) {
NSLog(@"[ERROR] Ti.UI.ApplicationShortcuts: The \"identifier\" property is required.");
return;
}

if ([args objectForKey:@"title"] == nil) {
NSLog(@"[ERROR] Ti.UI.ApplicationShortcuts: The \"title\" property is required.");
return;
}

if ([self typeExists:[args objectForKey:@"identifier"]]) {
NSLog(@"[ERROR] Ti.UI.ApplicationShortcuts: The identifier for the shortcut %@ already exists. This field must be unique.",
[args objectForKey:@"identifier"]);
return;
}

UIApplicationShortcutItem *shortcut = [[[UIApplicationShortcutItem alloc] initWithType:[args objectForKey:@"identifier"]
localizedTitle:[args objectForKey:@"title"]
localizedSubtitle:[args objectForKey:@"subtitle"]
icon:[self findIcon:[args objectForKey:@"icon"]]
userInfo:[args objectForKey:@"userInfo"]] autorelease];

NSMutableArray *shortcuts = (NSMutableArray *)[UIApplication sharedApplication].shortcutItems;
[shortcuts addObject:shortcut];
[UIApplication sharedApplication].shortcutItems = shortcuts;
}

- (UIApplicationShortcutIcon *)findIcon:(id)value
{
if (value == nil) {
return nil;
}

#ifdef USE_TI_CONTACTS
if ([value isKindOfClass:[TiContactsPerson class]]) {
ENSURE_TYPE(value, TiContactsPerson);
return [UIApplicationShortcutIcon iconWithContact:[(TiContactsPerson *)value nativePerson]];
}
#endif

if ([value isKindOfClass:[UIApplicationShortcutIcon class]]) {
return (UIApplicationShortcutIcon *)value;
}

if ([value isKindOfClass:[NSNumber class]]) {
NSInteger iconIndex = [value integerValue];
return [UIApplicationShortcutIcon iconWithType:iconIndex];
}

if ([value isKindOfClass:[NSString class]]) {
return [UIApplicationShortcutIcon iconWithTemplateImageName:[self urlInAssetCatalog:value]];
}

NSLog(@"[ERROR] Ti.UI.ApplicationShortcuts: Invalid icon provided, defaulting to use no icon.");
return nil;
}

- (NSString *)urlInAssetCatalog:(NSString *)url
{
NSString *resultUrl = nil;

if ([url hasPrefix:@"/"] == YES) {
url = [url substringFromIndex:1];
}

unsigned char digest[CC_SHA1_DIGEST_LENGTH];
NSData *stringBytes = [url dataUsingEncoding:NSUTF8StringEncoding];
if (CC_SHA1([stringBytes bytes], (CC_LONG)[stringBytes length], digest)) {
// SHA-1 hash has been calculated and stored in 'digest'.
NSMutableString *sha = [[NSMutableString alloc] init];
for (int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++) {
[sha appendFormat:@"%02x", digest[i]];
}
[sha appendString:@"."];
[sha appendString:[url pathExtension]];
resultUrl = [NSMutableString stringWithString:sha];
RELEASE_TO_NIL(sha)
}

return resultUrl;
}

@end
#endif
10 changes: 5 additions & 5 deletions iphone/Classes/TiUIiOSApplicationShortcutsProxy.m
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* Appcelerator Titanium Mobile
* Copyright (c) 2015 by Appcelerator, Inc. All Rights Reserved.
* Copyright (c) 2015-2018 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Apache Public License
* Please see the LICENSE included with this distribution for details.
*/
Expand Down Expand Up @@ -105,7 +105,7 @@ - (NSNumber *)dynamicShortcutExists:(id)itemtype
ENSURE_SINGLE_ARG(itemtype, NSString);

if ([TiUtils stringValue:itemtype] == nil) {
NSLog(@"[ERROR] Ti.UI.iOS.ApplicationShortcuts: The itemtype property is required.");
NSLog(@"[ERROR] Ti.UI.iOS.ApplicationShortcuts: The \"itemtype\" property is required.");
return;
}

Expand Down Expand Up @@ -133,7 +133,7 @@ - (void)removeDynamicShortcut:(id)itemtype
NSString *key = [TiUtils stringValue:itemtype];

if (key == nil) {
NSLog(@"[ERROR] The itemtype property is required.");
NSLog(@"[ERROR] The \"itemtype\" property is required.");
return;
}

Expand All @@ -157,12 +157,12 @@ - (void)addDynamicShortcut:(id)args
ENSURE_SINGLE_ARG(args, NSDictionary);

if ([args objectForKey:@"itemtype"] == nil) {
NSLog(@"[ERROR] Ti.UI.iOS.ApplicationShortcuts: The itemtype property is required.");
NSLog(@"[ERROR] Ti.UI.iOS.ApplicationShortcuts: The \"itemtype\" property is required.");
return;
}

if ([args objectForKey:@"title"] == nil) {
NSLog(@"[ERROR] Ti.UI.iOS.ApplicationShortcuts: The title property is required.");
NSLog(@"[ERROR] Ti.UI.iOS.ApplicationShortcuts: The \"title\" property is required.");
return;
}

Expand Down
2 changes: 1 addition & 1 deletion iphone/Classes/TiUIiOSProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@
- (id)createBlurView:(id)args;
#endif
#ifdef USE_TI_UIIOSAPPLICATIONSHORTCUTS
- (id)createApplicationShortcuts:(id)args;
- (id)createApplicationShortcuts:(id)args; // Deprecated in 7.1.0 in favor of API on Ti.UI namespace
#endif
#ifdef USE_TI_UIIOSFEEDBACKGENERATOR
- (id)createFeedbackGenerator:(id)args;
Expand Down
3 changes: 3 additions & 0 deletions iphone/Classes/TiUIiOSProxy.m
Original file line number Diff line number Diff line change
Expand Up @@ -728,9 +728,12 @@ - (id)createDynamicItemBehavior:(id)args
#ifdef USE_TI_UIIOSAPPLICATIONSHORTCUTS
- (id)createApplicationShortcuts:(id)args
{
DEPRECATED_REPLACED(@"UI.iOS.ApplicationShortcuts", @"7.5.0", @"UI.ApplicationShortcuts");
return [[[TiUIiOSApplicationShortcutsProxy alloc] _initWithPageContext:[self executionContext] args:args] autorelease];
}
#endif

#if defined(USE_TI_UIIOSAPPLICATIONSHORTCUTS) || defined(USE_TI_UIAPPLICATIONSHORTCUTS)
MAKE_SYSTEM_PROP(SHORTCUT_ICON_TYPE_COMPOSE, UIApplicationShortcutIconTypeCompose);
MAKE_SYSTEM_PROP(SHORTCUT_ICON_TYPE_PLAY, UIApplicationShortcutIconTypePlay);
MAKE_SYSTEM_PROP(SHORTCUT_ICON_TYPE_PAUSE, UIApplicationShortcutIconTypePause);
Expand Down
2 changes: 2 additions & 0 deletions iphone/Classes/defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
#define USE_TI_UIATTRIBUTEDSTRING
#define USE_TI_UIACTIVITYINDICATORSTYLE
#define USE_TI_UITOOLBAR
#define USE_TI_UIAPPLICATIONSHORTCUTS
#define USE_TI_UINAVIGATIONWINDOW

#define USE_TI_UIIPHONE
Expand Down Expand Up @@ -139,6 +140,7 @@
#define USE_TI_UIIOSTRANSITIONANIMATION
#define USE_TI_UIREFRESHCONTROL
#define USE_TI_UIIOSAPPLICATIONSHORTCUTS

#define USE_TI_UIIOSBLURVIEW
#define USE_TI_NETWORKREGISTERFORPUSHNOTIFICATIONS
#define USE_TI_SILENTPUSH
Expand Down
14 changes: 14 additions & 0 deletions iphone/iphone/Titanium.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@
DB90749F1D84299500BB0FD5 /* TiUIiOSFeedbackGeneratorProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = DB90749E1D84299500BB0FD5 /* TiUIiOSFeedbackGeneratorProxy.m */; };
DBCE968920FCEF1600B47572 /* KrollWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = DBCE968820FCEF1600B47572 /* KrollWrapper.m */; };
DBCFCB7C1F8261BF00A4CE61 /* SBJSON.m in Sources */ = {isa = PBXBuildFile; fileRef = DBCFCB7B1F8261BF00A4CE61 /* SBJSON.m */; };
DBF4B13B200FD93400777136 /* TiUIApplicationShortcutsProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = DBF4B13A200FD93400777136 /* TiUIApplicationShortcutsProxy.m */; };
EF0ADCFA143F9ABF00977386 /* NSData+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = EF0ADCF9143F9ABF00977386 /* NSData+Additions.m */; };
EF0ADD1A143FA0CD00977386 /* GeolocationModule.m in Sources */ = {isa = PBXBuildFile; fileRef = EF0ADD19143FA0CD00977386 /* GeolocationModule.m */; };
/* End PBXBuildFile section */
Expand Down Expand Up @@ -971,6 +972,8 @@
DBCE968820FCEF1600B47572 /* KrollWrapper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = KrollWrapper.m; path = ../Classes/KrollWrapper.m; sourceTree = "<group>"; };
DBCFCB7A1F8261BF00A4CE61 /* SBJSON.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBJSON.h; path = ../Classes/SBJSON.h; sourceTree = "<group>"; };
DBCFCB7B1F8261BF00A4CE61 /* SBJSON.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SBJSON.m; path = ../Classes/SBJSON.m; sourceTree = "<group>"; };
DBF4B139200FD93400777136 /* TiUIApplicationShortcutsProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TiUIApplicationShortcutsProxy.h; sourceTree = "<group>"; };
DBF4B13A200FD93400777136 /* TiUIApplicationShortcutsProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TiUIApplicationShortcutsProxy.m; sourceTree = "<group>"; };
DBE07F2D20AC4B42000307EA /* APSUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APSUtility.h; sourceTree = "<group>"; };
EF0ADCF9143F9ABF00977386 /* NSData+Additions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSData+Additions.m"; path = "../Classes/NSData+Additions.m"; sourceTree = "<group>"; };
EF0ADD19143FA0CD00977386 /* GeolocationModule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeolocationModule.m; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1424,6 +1427,7 @@
24CA8C14111164040084E2DE /* UI */ = {
isa = PBXGroup;
children = (
DBF4B138200FD90600777136 /* Application Shortcuts */,
DB4E9B7020B2E9510064ADF9 /* Navigation Window */,
DB0D54921F3B491300E2B771 /* Toolbar */,
BBDD81351A2C71E5003CDA10 /* AttributedString */,
Expand Down Expand Up @@ -2437,6 +2441,15 @@
name = SBJSON;
sourceTree = "<group>";
};
DBF4B138200FD90600777136 /* Application Shortcuts */ = {
isa = PBXGroup;
children = (
DBF4B139200FD93400777136 /* TiUIApplicationShortcutsProxy.h */,
DBF4B13A200FD93400777136 /* TiUIApplicationShortcutsProxy.m */,
);
name = "Application Shortcuts";
sourceTree = "<group>";
};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
Expand Down Expand Up @@ -2592,6 +2605,7 @@
24CA8B80111161FE0084E2DE /* TiUITableViewProxy.m in Sources */,
24CA8B84111161FE0084E2DE /* TiUITableView.m in Sources */,
159C59981C358538009A8860 /* TiUIiOSAnimationStyleProxy.m in Sources */,
DBF4B13B200FD93400777136 /* TiUIApplicationShortcutsProxy.m in Sources */,
24CA8B85111161FE0084E2DE /* TiUITabGroupProxy.m in Sources */,
24CA8B86111161FE0084E2DE /* TiUITabGroup.m in Sources */,
24CA8B8C111161FE0084E2DE /* TiUISwitchProxy.m in Sources */,
Expand Down

0 comments on commit fcbd951

Please sign in to comment.