Skip to content

Commit

Permalink
feat(ios): move application shortcut under Ti.UI.Shortcut to have parity
Browse files Browse the repository at this point in the history
Fixes TIMOB-26818
  • Loading branch information
vijaysingh-axway authored and sgtcoolguy committed Jul 17, 2020
1 parent 50c4a5c commit 8446d39
Show file tree
Hide file tree
Showing 7 changed files with 369 additions and 0 deletions.
32 changes: 32 additions & 0 deletions iphone/Classes/TiUIShortcutItemProxy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Appcelerator Titanium Mobile
* Copyright (c) 2020 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_UISHORTCUT) || defined(USE_TI_UISHORTCUTITEM)
#import <TitaniumKit/ObjcProxy.h>

NS_ASSUME_NONNULL_BEGIN
@protocol TiUIShortcutItemProxyExports <JSExport>

READONLY_PROPERTY(NSString *, title, Title);
READONLY_PROPERTY(NSString *, description, Description);
READONLY_PROPERTY(NSDictionary *, data, Data);
READONLY_PROPERTY(id, icon, Icon);
READONLY_PROPERTY(NSString *, id, Id);

@end

@interface TiUIShortcutItemProxy : ObjcProxy <TiUIShortcutItemProxyExports> {
UIApplicationShortcutItem *_shortcutItem;
}

// Internal use only
- (id)initWithShortcutItem:(UIApplicationShortcutItem *)item;
- (UIApplicationShortcutItem *)shortcutItem;

@end

NS_ASSUME_NONNULL_END
#endif
130 changes: 130 additions & 0 deletions iphone/Classes/TiUIShortcutItemProxy.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/**
* Appcelerator Titanium Mobile
* Copyright (c) 2020 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_UISHORTCUT) || defined(USE_TI_UISHORTCUTITEM)

#import "TiUIShortcutItemProxy.h"
#import <TitaniumKit/TiBlob.h>
#import <TitaniumKit/TiUtils.h>
#ifdef USE_TI_CONTACTS
#import "TiContactsPerson.h"
#import <ContactsUI/ContactsUI.h>
#endif
@implementation TiUIShortcutItemProxy

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

- (void)dealloc
{
RELEASE_TO_NIL(_shortcutItem);

[super dealloc];
}

- (id)_initWithPageContext:(id<TiEvaluator>)context_ args:(NSArray *)args
{
if (self = [self _initWithPageContext:context_]) {
ENSURE_SINGLE_ARG(args, NSDictionary);
if ([args valueForKey:@"id"] == nil) {
NSLog(@"[ERROR] Ti.UI.ShortcutItem: The \"id\" property is required.");
return;
}

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

_shortcutItem = [[UIApplicationShortcutItem alloc] initWithType:[args valueForKey:@"id"]
localizedTitle:[args valueForKey:@"title"]
localizedSubtitle:[args valueForKey:@"description"]
icon:[self findIcon:[args valueForKey:@"icon"]]
userInfo:[args valueForKey:@"data"]];
}
return self;
}

- (id)initWithShortcutItem:(UIApplicationShortcutItem *)item
{
if (self = [super init]) {
_shortcutItem = [item retain];
}
return self;
}

- (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]]) {
value = ([value hasPrefix:@"/"]) ? [value substringFromIndex:1] : value;
return [UIApplicationShortcutIcon iconWithTemplateImageName:value];
}

#if IS_SDK_IOS_13
if ([value isKindOfClass:[TiBlob class]] && [TiUtils isIOSVersionOrGreater:@"13.0"]) {
TiBlob *blob = (TiBlob *)value;
if (blob.type == TiBlobTypeSystemImage) {
return [UIApplicationShortcutIcon iconWithSystemImageName:blob.systemImageName];
}
}
#endif
NSLog(@"[ERROR] Ti.UI.ApplicationShortcuts: Invalid icon provided, defaulting to use no icon.");
return nil;
}

- (UIApplicationShortcutItem *)shortcutItem
{
return _shortcutItem;
}

- (NSString *)id
{
return _shortcutItem.type;
}

- (NSString *)title
{
return _shortcutItem.localizedTitle;
}

- (NSString *)description
{
return _shortcutItem.localizedSubtitle;
}

- (NSDictionary *)data
{
return _shortcutItem.userInfo;
}

- (id)icon
{
return _shortcutItem.icon;
}
@end
#endif
34 changes: 34 additions & 0 deletions iphone/Classes/TiUIShortcutProxy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* Appcelerator Titanium Mobile
* Copyright (c) 2020 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_UISHORTCUT) || defined(USE_TI_UISHORTCUTITEM)

#import <TitaniumKit/ObjcProxy.h>

@class TiUIShortcutItemProxy;

NS_ASSUME_NONNULL_BEGIN

@protocol TiUIShortcutProxyExports <JSExport>
READONLY_PROPERTY(NSArray<TiUIShortcutItemProxy *> *, items, Items);
READONLY_PROPERTY(NSArray<TiUIShortcutItemProxy *> *, staticItems, StaticItems);

- (TiUIShortcutItemProxy *)getById:(NSString *)identifier;

- (void)remove:(TiUIShortcutItemProxy *)shortcut;

- (void)removeAll;
- (void)add:(TiUIShortcutItemProxy *)shortcut;

@end

@interface TiUIShortcutProxy : ObjcProxy <TiUIShortcutProxyExports>

@end

NS_ASSUME_NONNULL_END
#endif
158 changes: 158 additions & 0 deletions iphone/Classes/TiUIShortcutProxy.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
/**
* Appcelerator Titanium Mobile
* Copyright (c) 2020 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_UISHORTCUT) || defined(USE_TI_UISHORTCUTITEM)

#import "TiUIShortcutProxy.h"
#import "TiUIShortcutItemProxy.h"
#import <TitaniumKit/TiUtils.h>

@implementation TiUIShortcutProxy

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

- (id)init
{
if (self = [super init]) {
}
return self;
}

- (void)_destroy
{
TiThreadPerformOnMainThread(
^{
[[NSNotificationCenter defaultCenter] removeObserver:self];
},
YES);
[super _destroy];
}

- (void)_listenerAdded:(NSString *)type count:(int)count
{
if (count == 1 && [type isEqualToString:@"click"]) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector
(didReceiveApplicationShortcutNotification1:)
name:kTiApplicationShortcut
object:nil];
[self retain];
}
}

- (void)_listenerRemoved:(NSString *)type count:(int)count
{
if (count == 0 && [type isEqualToString:@"click"]) {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self release];
}
}

- (NSArray<TiUIShortcutItemProxy *> *)items
{
NSMutableArray<TiUIShortcutItemProxy *> *shortcutsToReturn = [NSMutableArray array];
NSArray<UIApplicationShortcutItem *> *shortcuts = [UIApplication sharedApplication].shortcutItems;

for (UIApplicationShortcutItem *item in shortcuts) {
[shortcutsToReturn addObject:[[[TiUIShortcutItemProxy alloc] initWithShortcutItem:item] autorelease]];
}

return shortcutsToReturn;
}

- (NSArray<TiUIShortcutItemProxy *> *)staticItems
{
NSMutableArray<TiUIShortcutItemProxy *> *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:[[[TiUIShortcutItemProxy alloc] initWithShortcutItem:shortcut] autorelease]];
}

return shortcutsToReturn;
}

- (TiUIShortcutItemProxy *)getById:(NSString *)identifier
{
NSArray<UIApplicationShortcutItem *> *shortcuts = [UIApplication sharedApplication].shortcutItems;
for (UIApplicationShortcutItem *item in shortcuts) {
if ([item.type isEqualToString:[TiUtils stringValue:identifier]]) {
return [[[TiUIShortcutItemProxy alloc] initWithShortcutItem:item] autorelease];
}
}

return nil;
}

- (void)remove:(TiUIShortcutItemProxy *)shortcut
{
NSString *key = [shortcut shortcutItem].type;

NSMutableArray<UIApplicationShortcutItem *> *shortcuts = (NSMutableArray<UIApplicationShortcutItem *> *)[UIApplication sharedApplication].shortcutItems;
for (UIApplicationShortcutItem *item in shortcuts) {
if ([item.type isEqualToString:[shortcut shortcutItem].type]) {
[shortcuts removeObject:item];
break;
}
}
[UIApplication sharedApplication].shortcutItems = shortcuts;
}

- (void)removeAll
{
[UIApplication sharedApplication].shortcutItems = nil;
}

- (void)add:(TiUIShortcutItemProxy *)shortcut
{
NSMutableArray<UIApplicationShortcutItem *> *shortcuts = (NSMutableArray<UIApplicationShortcutItem *> *)[UIApplication sharedApplication].shortcutItems;

// Remove previous shortcutitem of same id if exists
__block NSUInteger index = shortcuts.count;
[shortcuts enumerateObjectsUsingBlock:^(UIApplicationShortcutItem *_Nonnull item, NSUInteger idx, BOOL *_Nonnull stop) {
if ([item.type isEqualToString:[shortcut shortcutItem].type]) {
index = idx;
[shortcuts removeObject:item];
*stop = true;
}
}];
[shortcuts insertObject:[shortcut shortcutItem] atIndex:index];
[UIApplication sharedApplication].shortcutItems = shortcuts;
}

- (void)didReceiveApplicationShortcutNotification1:(NSNotification *)info
{
if ([self _hasListeners:@"click"]) {
UIApplicationShortcutItem *shortcut = [[[UIApplicationShortcutItem alloc] initWithType:[[info userInfo] valueForKey:@"type"]
localizedTitle:[[info userInfo] valueForKey:@"title"]
localizedSubtitle:[[info userInfo] valueForKey:@"subtitle"]
icon:nil
userInfo:[[info userInfo] objectForKey:@"userInfo"]] autorelease];
[self fireEvent:@"click" withDict:@{ @"item" : [[[TiUIShortcutItemProxy alloc] initWithShortcutItem:shortcut] autorelease] }];
}
}
@end
#endif
1 change: 1 addition & 0 deletions iphone/Classes/TiUIiOSProxy.m
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,7 @@ - (id)createDynamicItemBehavior:(id)args
#ifdef USE_TI_UIIOSAPPLICATIONSHORTCUTS
- (id)createApplicationShortcuts:(id)args
{
DEPRECATED_REPLACED(@"UI.iOS.ApplicationShortcuts", @"9.1.0", @"UI.Shortcut");
return [[[TiUIiOSApplicationShortcutsProxy alloc] _initWithPageContext:[self executionContext] args:args] autorelease];
}
#endif
Expand Down
2 changes: 2 additions & 0 deletions iphone/Classes/defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@
#define USE_TI_UIIOSTRANSITIONANIMATION
#define USE_TI_UIREFRESHCONTROL
#define USE_TI_UIIOSAPPLICATIONSHORTCUTS
#define USE_TI_UISHORTCUT
#define USE_TI_UISHORTCUTITEM

#define USE_TI_UIIOSBLURVIEW
#define USE_TI_NETWORKREGISTERFORPUSHNOTIFICATIONS
Expand Down
Loading

0 comments on commit 8446d39

Please sign in to comment.