From acda1f3ef69b9f2d29c0f71632b7e8500632107d Mon Sep 17 00:00:00 2001 From: AbdullahFaqeir Date: Mon, 14 Oct 2024 18:28:08 +0300 Subject: [PATCH 1/3] feat(ios): added support for iOS 18 dark mode icons --- .../AppIcon.appiconset/Contents.json | 26 ++++- .../AppIcon.appiconset/Contents.json | 103 +++++++++++++----- 2 files changed, 101 insertions(+), 28 deletions(-) diff --git a/iphone/iphone/Assets.xcassets/AppIcon.appiconset/Contents.json b/iphone/iphone/Assets.xcassets/AppIcon.appiconset/Contents.json index 973aa2af684..9e8bc4f3e7f 100644 --- a/iphone/iphone/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/iphone/iphone/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -103,10 +103,34 @@ "idiom" : "ios-marketing", "filename" : "appicon-1024.png", "scale" : "1x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "DefaultIcon-Dark.png", + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "tinted" + } + ], + "filename" : "DefaultIcon-Tinted.png", + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" } ], "info" : { "version" : 1, "author" : "xcode" } -} \ No newline at end of file +} diff --git a/iphone/layout/layout/Assets.xcassets/AppIcon.appiconset/Contents.json b/iphone/layout/layout/Assets.xcassets/AppIcon.appiconset/Contents.json index 36d2c80d889..c7628d8b56a 100644 --- a/iphone/layout/layout/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/iphone/layout/layout/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,68 +1,117 @@ { "images" : [ + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "DefaultIcon-Dark.png", + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "tinted" + } + ], + "filename" : "DefaultIcon-Tinted.png", + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "20x20" + }, { "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" + "scale" : "2x", + "size" : "29x29" }, { "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" + "scale" : "3x", + "size" : "29x29" }, { "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" + "scale" : "2x", + "size" : "40x40" }, { "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" + "scale" : "3x", + "size" : "40x40" }, { "idiom" : "iphone", - "size" : "60x60", - "scale" : "2x" + "scale" : "2x", + "size" : "60x60" }, { "idiom" : "iphone", - "size" : "60x60", - "scale" : "3x" + "scale" : "3x", + "size" : "60x60" }, { "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" + "scale" : "2x", + "size" : "20x20" }, { "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" + "scale" : "1x", + "size" : "29x29" }, { "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" + "scale" : "2x", + "size" : "29x29" }, { "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" + "scale" : "1x", + "size" : "40x40" }, { "idiom" : "ipad", - "size" : "76x76", - "scale" : "1x" + "scale" : "2x", + "size" : "40x40" }, { "idiom" : "ipad", - "size" : "76x76", - "scale" : "2x" + "scale" : "1x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 } -} \ No newline at end of file +} From 7f82fba5ce52ba81c87aea306a1d3c1c1878a8cd Mon Sep 17 00:00:00 2001 From: AbdullahFaqeir Date: Sat, 9 Nov 2024 22:00:43 +0300 Subject: [PATCH 2/3] feat(ios): reviving PR (#12411) for ios Background tasks --- iphone/Classes/TiAppiOSProxy.m | 36 +++++ .../TitaniumKit.xcodeproj/project.pbxproj | 2 +- .../TitaniumKit/Sources/API/TiApp.h | 10 +- .../TitaniumKit/Sources/API/TiApp.m | 131 +++++++++++++++++- .../TitaniumKit/Sources/API/TiBase.h | 1 + .../TitaniumKit/Sources/API/TiBase.m | 1 + .../iphone/Titanium.xcodeproj/project.pbxproj | 2 + 7 files changed, 174 insertions(+), 9 deletions(-) diff --git a/iphone/Classes/TiAppiOSProxy.m b/iphone/Classes/TiAppiOSProxy.m index 695bade5536..cfb7c862f1e 100644 --- a/iphone/Classes/TiAppiOSProxy.m +++ b/iphone/Classes/TiAppiOSProxy.m @@ -161,9 +161,20 @@ - (void)_listenerRemoved:(NSString *)type count:(int)count if ((count == 1) && [type isEqual:@"backgroundfetch"]) { [[NSNotificationCenter defaultCenter] removeObserver:self name:kTiBackgroundFetchNotification object:nil]; } + if ((count == 1) && [type isEqual:@"backgroundprocess"]) { + [[NSNotificationCenter defaultCenter] removeObserver:self name:kTiBackgroundProcessNotification object:nil]; + } if ((count == 1) && [type isEqual:@"sessioneventscompleted"]) { [[NSNotificationCenter defaultCenter] removeObserver:self name:kTiURLSessionEventsCompleted object:nil]; } + if ((count == 1) && [type isEqual:@"backgroundprocess"]) { + NSArray *backgroundModes = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIBackgroundModes"]; + if ([backgroundModes containsObject:@"processing"]) { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveBackgroundProcessNotification:) name:kTiBackgroundProcessNotification object:nil]; + } else { + DebugLog(@"[ERROR] Cannot add backgroundprocess eventListener. Please add `processing` to UIBackgroundModes inside info.plist "); + } + } if ((count == 1) && [type isEqual:@"silentpush"]) { [[NSNotificationCenter defaultCenter] removeObserver:self name:kTiSilentPushNotification object:nil]; } @@ -407,6 +418,20 @@ - (TiAppiOSBackgroundServiceProxy *)registerBackgroundService:(id)args return proxy; } +- (void)registerBackgroundTask:(id)args +{ + ENSURE_SINGLE_ARG(args, NSDictionary); + ENSURE_STRING(args[@"identifier"]); + ENSURE_STRING(args[@"type"]); + + if ([TiUtils isIOSVersionLower:@"13.0"]) { + DebugLog(@"This API is not supported fo iOS < 13.0"); + return; + } + + [[TiApp app] addBackgroundTask:args]; +} + - (void)registerUserNotificationSettings:(id)args { ENSURE_SINGLE_ARG(args, NSDictionary); @@ -889,6 +914,11 @@ - (void)didReceiveBackgroundFetchNotification:(NSNotification *)note [self fireEvent:@"backgroundfetch" withObject:[note userInfo]]; } +- (void)didReceiveBackgroundProcessNotification:(NSNotification *)note +{ + [self fireEvent:@"backgroundprocess" withObject:[note userInfo]]; +} + - (void)didReceiveSilentPushNotification:(NSNotification *)note { [self fireEvent:@"silentpush" withObject:[note userInfo]]; @@ -975,6 +1005,9 @@ - (void)endBackgroundHandler:(id)handlerIdentifier if ([handlerIdentifier rangeOfString:@"Session"].location != NSNotFound) { [[TiApp app] performCompletionHandlerForBackgroundTransferWithKey:handlerIdentifier]; + } else if ([handlerIdentifier hasPrefix:@"BgTask-"]) { + // handlerId = @"BgTask-" + BgTask.identifier. So remove @"BgTask-" to get actual BgTask identifier. + [[TiApp app] backgroundTaskCompletedForIdentifier:[handlerIdentifier substringFromIndex:7]]; } else { [[TiApp app] performCompletionHandlerWithKey:handlerIdentifier andResult:UIBackgroundFetchResultNoData removeAfterExecution:NO]; } @@ -1338,6 +1371,9 @@ - (NSString *)applicationOpenSettingsURL MAKE_SYSTEM_PROP(USER_NOTIFICATION_ALERT_STYLE_ALERT, UNAlertStyleAlert); MAKE_SYSTEM_PROP(USER_NOTIFICATION_ALERT_STYLE_BANNER, UNAlertStyleBanner); +MAKE_SYSTEM_STR(BACKGROUND_TASK_TYPE_REFRESH, @"refresh"); +MAKE_SYSTEM_STR(BACKGROUND_TASK_TYPE_PROCESS, @"process"); + @end #endif diff --git a/iphone/TitaniumKit/TitaniumKit.xcodeproj/project.pbxproj b/iphone/TitaniumKit/TitaniumKit.xcodeproj/project.pbxproj index 9edd4a2fad5..ec9ba203e1b 100644 --- a/iphone/TitaniumKit/TitaniumKit.xcodeproj/project.pbxproj +++ b/iphone/TitaniumKit/TitaniumKit.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 52; + objectVersion = 54; objects = { /* Begin PBXAggregateTarget section */ diff --git a/iphone/TitaniumKit/TitaniumKit/Sources/API/TiApp.h b/iphone/TitaniumKit/TitaniumKit/Sources/API/TiApp.h index fb3769d87ce..c25c6dd153c 100644 --- a/iphone/TitaniumKit/TitaniumKit/Sources/API/TiApp.h +++ b/iphone/TitaniumKit/TitaniumKit/Sources/API/TiApp.h @@ -11,6 +11,7 @@ #import "KrollBridge.h" #import "TiHost.h" #import "TiRootViewController.h" +#import #import extern BOOL applicationInMemoryPanic; // TODO: Remove in SDK 9.0+ @@ -56,8 +57,12 @@ TI_INLINE void waitForMemoryPanicCleared() // WARNING: This must never be run on NSString *sessionId; - UIBackgroundTaskIdentifier bgTask; + UIBackgroundTaskIdentifier bgTaskIdentifier; NSMutableArray *backgroundServices; + + NSMutableArray *backgroundTasks; + NSMutableArray *registeredBackgroundTasks; + NSMutableArray *runningServices; NSDictionary *localNotification; UIApplicationShortcutItem *launchedShortcutItem; @@ -294,6 +299,9 @@ TI_INLINE void waitForMemoryPanicCleared() // WARNING: This must never be run on */ - (void)tryToPostBackgroundModeNotification:(NSMutableDictionary *)userInfo withNotificationName:(NSString *)notificationName; +- (void)addBackgroundTask:(NSDictionary *)bgTask; +- (void)backgroundTaskCompletedForIdentifier:(NSString *)identifier; + - (void)registerBackgroundService:(TiProxy *)proxy; - (void)unregisterBackgroundService:(TiProxy *)proxy; - (void)stopBackgroundService:(TiProxy *)proxy; diff --git a/iphone/TitaniumKit/TitaniumKit/Sources/API/TiApp.m b/iphone/TitaniumKit/TitaniumKit/Sources/API/TiApp.m index 35c3346f7bc..0496b016ceb 100644 --- a/iphone/TitaniumKit/TitaniumKit/Sources/API/TiApp.m +++ b/iphone/TitaniumKit/TitaniumKit/Sources/API/TiApp.m @@ -433,6 +433,10 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( // Create application support directory if not exists [self createDefaultDirectories]; + if ([TiUtils isIOSVersionOrGreater:@"13.0"]) { + [self registerBackgroundTasks]; + } + return YES; } @@ -1083,20 +1087,26 @@ - (void)applicationDidEnterBackground:(UIApplication *)application [[NSNotificationCenter defaultCenter] postNotificationName:kTiPausedNotification object:self]; + if ([TiUtils isIOSVersionOrGreater:@"13.0"]) { + for (NSDictionary *backgroundTask in backgroundTasks) { + [self submitBackgroundTask:backgroundTask]; + } + } + if (backgroundServices == nil) { return; } UIApplication *app = [UIApplication sharedApplication]; TiApp *tiapp = self; - bgTask = [app beginBackgroundTaskWithExpirationHandler:^{ + bgTaskIdentifier = [app beginBackgroundTaskWithExpirationHandler:^{ // Synchronize the cleanup call on the main thread in case // the task actually finishes at around the same time. TiThreadPerformOnMainThread( ^{ - if (bgTask != UIBackgroundTaskInvalid) { - [app endBackgroundTask:bgTask]; - bgTask = UIBackgroundTaskInvalid; + if (bgTaskIdentifier != UIBackgroundTaskInvalid) { + [app endBackgroundTask:bgTaskIdentifier]; + bgTaskIdentifier = UIBackgroundTaskInvalid; } }, NO); @@ -1202,6 +1212,8 @@ - (void)dealloc RELEASE_TO_NIL(queuedBootEvents); RELEASE_TO_NIL(_queuedApplicationSelectors); RELEASE_TO_NIL(_applicationDelegates); + RELEASE_TO_NIL(backgroundTasks); + RELEASE_TO_NIL(registeredBackgroundTasks); [super dealloc]; } @@ -1237,6 +1249,111 @@ - (KrollBridge *)krollBridge #pragma mark Background Tasks +- (void)registerBackgroundTasks +{ + NSArray *identifiers = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"BGTaskSchedulerPermittedIdentifiers"]; + + for (NSString *identifier in identifiers) { + if (registeredBackgroundTasks == nil) { + registeredBackgroundTasks = [[NSMutableArray alloc] init]; + } + [[BGTaskScheduler sharedScheduler] registerForTaskWithIdentifier:identifier + usingQueue:nil + launchHandler:^(__kindof BGTask *_Nonnull task) { + [registeredBackgroundTasks addObject:task]; + [self handleBGTask:task]; + }]; + } +} + +- (void)handleBGTask:(BGTask *)task +{ + NSString *notificationName = kTiBackgroundProcessNotification; + if ([task isKindOfClass:[BGAppRefreshTask class]]) { + // Fo refresh task submit it again + [self submitTaskForIdentifier:task.identifier]; + notificationName = kTiBackgroundFetchNotification; + } + NSString *key = [NSString stringWithFormat:@"BgTask-%@", task.identifier]; + + [self tryToPostBackgroundModeNotification:[NSMutableDictionary dictionaryWithObjectsAndKeys:key, @"handlerId", nil] + withNotificationName:notificationName]; + + task.expirationHandler = ^{ + if ([task isKindOfClass:[BGProcessingTask class]]) { + // Fo processing task, if it is not completed in time then only submit it again. + [self submitTaskForIdentifier:task.identifier]; + } + [task setTaskCompletedWithSuccess:false]; + [registeredBackgroundTasks removeObject:task]; + }; +} + +- (void)submitTaskForIdentifier:(NSString *)identifier +{ + NSDictionary *backgroundTask = [self backgroundTaskForIdentifier:identifier]; + if (backgroundTask) { + [self submitBackgroundTask:backgroundTask]; + } +} + +- (void)submitBackgroundTask:(NSDictionary *)bgTask +{ + BGTaskRequest *taskRequest; + if ([bgTask[@"type"] isEqualToString:@"process"]) { + taskRequest = [[[BGProcessingTaskRequest alloc] initWithIdentifier:bgTask[@"identifier"]] autorelease]; + ((BGProcessingTaskRequest *)taskRequest).requiresNetworkConnectivity = [TiUtils boolValue:bgTask[@"networkConnect"] def:NO]; + ((BGProcessingTaskRequest *)taskRequest).requiresExternalPower = [TiUtils boolValue:bgTask[@"powerConnect"] def:NO]; + } else { + taskRequest = [[[BGAppRefreshTaskRequest alloc] initWithIdentifier:bgTask[@"identifier"]] autorelease]; + } + taskRequest.earliestBeginDate = bgTask[@"beginDate"]; + + [BGTaskScheduler.sharedScheduler submitTaskRequest:taskRequest error:nil]; +} + +- (void)backgroundTaskCompletedForIdentifier:(NSString *)identifier +{ + for (BGTask *task in registeredBackgroundTasks) { + if ([task.identifier isEqualToString:identifier]) { + [task setTaskCompletedWithSuccess:YES]; + [registeredBackgroundTasks removeObject:task]; + break; + } + } +} + +- (NSDictionary *_Nullable)backgroundTaskForIdentifier:(NSString *)identifier +{ + NSDictionary *bgTask = nil; + for (NSDictionary *backgroundTask in backgroundTasks) { + if (backgroundTask[@"identifier"] == identifier) { + bgTask = backgroundTask; + break; + } + } + return bgTask; +} + +- (void)addBackgroundTask:(NSDictionary *)backgroundTask +{ + if (backgroundTasks == nil) { + backgroundTasks = [[NSMutableArray alloc] init]; + } + NSArray *identifiers = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"BGTaskSchedulerPermittedIdentifiers"]; + NSDictionary *oldTask = [self backgroundTaskForIdentifier:backgroundTask[@"identifier"]]; + if ([identifiers containsObject:backgroundTask[@"identifier"]]) { + if (oldTask) { + [backgroundTasks removeObject:oldTask]; + } + [backgroundTasks addObject:backgroundTask]; + } else { + DebugLog(@"The identifier, %@, is not added in tiapp.xml. Add it against key BGTaskSchedulerPermittedIdentifiers", backgroundTask[@"identifier"]); + } +} + +#pragma mark Background Services + - (void)beginBackgrounding { if (runningServices == nil) { @@ -1383,9 +1500,9 @@ - (void)checkBackgroundServices // the expiration handler is fired at the same time. TiThreadPerformOnMainThread( ^{ - if (bgTask != UIBackgroundTaskInvalid) { - [[UIApplication sharedApplication] endBackgroundTask:bgTask]; - bgTask = UIBackgroundTaskInvalid; + if (bgTaskIdentifier != UIBackgroundTaskInvalid) { + [[UIApplication sharedApplication] endBackgroundTask:bgTaskIdentifier]; + bgTaskIdentifier = UIBackgroundTaskInvalid; } }, NO); diff --git a/iphone/TitaniumKit/TitaniumKit/Sources/API/TiBase.h b/iphone/TitaniumKit/TitaniumKit/Sources/API/TiBase.h index 3ae6ba65370..eb581d664db 100644 --- a/iphone/TitaniumKit/TitaniumKit/Sources/API/TiBase.h +++ b/iphone/TitaniumKit/TitaniumKit/Sources/API/TiBase.h @@ -591,6 +591,7 @@ extern NSString *const kTiRemoteDeviceUUIDNotification; extern NSString *const kTiGestureShakeNotification; extern NSString *const kTiRemoteControlNotification; extern NSString *const kTiBackgroundFetchNotification; +extern NSString *const kTiBackgroundProcessNotification; extern NSString *const kTiSilentPushNotification; extern NSString *const kTiBackgroundTransfer; extern NSString *const kTiCurrentLocale; diff --git a/iphone/TitaniumKit/TitaniumKit/Sources/API/TiBase.m b/iphone/TitaniumKit/TitaniumKit/Sources/API/TiBase.m index f7477e2322c..7cf22e3196f 100644 --- a/iphone/TitaniumKit/TitaniumKit/Sources/API/TiBase.m +++ b/iphone/TitaniumKit/TitaniumKit/Sources/API/TiBase.m @@ -95,6 +95,7 @@ void TiLogMessage(NSString *str, ...) NSString *const kTiGestureShakeNotification = @"TiGestureShake"; NSString *const kTiRemoteControlNotification = @"TiRemoteControl"; NSString *const kTiBackgroundFetchNotification = @"TiBackgroundFetch"; +NSString *const kTiBackgroundProcessNotification = @"TiBackgroundProcess"; NSString *const kTiSilentPushNotification = @"TiSilentPush"; NSString *const kTiBackgroundTransfer = @"TiBackgroundTransfer"; NSString *const kTiCurrentLocale = @"kTiCurrentLocale"; diff --git a/iphone/iphone/Titanium.xcodeproj/project.pbxproj b/iphone/iphone/Titanium.xcodeproj/project.pbxproj index 5a110b83e4a..b9ab52c3b3c 100644 --- a/iphone/iphone/Titanium.xcodeproj/project.pbxproj +++ b/iphone/iphone/Titanium.xcodeproj/project.pbxproj @@ -2391,6 +2391,7 @@ DEVELOPMENT_TEAM = ""; ENABLE_BITCODE = NO; "ENABLE_HARDENED_RUNTIME[sdk=macosx*]" = YES; + EXCLUDED_ARCHS = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_CPP_RTTI = NO; GCC_OPTIMIZATION_LEVEL = 0; @@ -2454,6 +2455,7 @@ ENABLE_BITCODE = NO; "ENABLE_HARDENED_RUNTIME[sdk=macosx*]" = YES; ENABLE_NS_ASSERTIONS = NO; + EXCLUDED_ARCHS = ""; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = Titanium_Prefix.pch; GCC_PREPROCESSOR_DEFINITIONS = ( From 08b795aea475e80440f3de19576ee033a94e4950 Mon Sep 17 00:00:00 2001 From: AbdullahFaqeir Date: Sat, 9 Nov 2024 22:30:02 +0300 Subject: [PATCH 3/3] feat(ios): remove mixed code from another PR/commit --- .../AppIcon.appiconset/Contents.json | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/iphone/iphone/Assets.xcassets/AppIcon.appiconset/Contents.json b/iphone/iphone/Assets.xcassets/AppIcon.appiconset/Contents.json index 9e8bc4f3e7f..e6e0ceb7c00 100644 --- a/iphone/iphone/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/iphone/iphone/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -103,30 +103,6 @@ "idiom" : "ios-marketing", "filename" : "appicon-1024.png", "scale" : "1x" - }, - { - "appearances" : [ - { - "appearance" : "luminosity", - "value" : "dark" - } - ], - "filename" : "DefaultIcon-Dark.png", - "idiom" : "universal", - "platform" : "ios", - "size" : "1024x1024" - }, - { - "appearances" : [ - { - "appearance" : "luminosity", - "value" : "tinted" - } - ], - "filename" : "DefaultIcon-Tinted.png", - "idiom" : "universal", - "platform" : "ios", - "size" : "1024x1024" } ], "info" : {