diff --git a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj index 0760bf2c0..6c7379d26 100644 --- a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj +++ b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj @@ -1238,6 +1238,8 @@ 756C62772289F11F008B57A2 /* SDLDynamicMenuUpdateRunScore.m in Sources */ = {isa = PBXBuildFile; fileRef = 756C62752289F11F008B57A2 /* SDLDynamicMenuUpdateRunScore.m */; }; 880245A420F79C3400ED195B /* SDLFileManagerConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 880245A220F79C3400ED195B /* SDLFileManagerConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; }; 880245A520F79C3400ED195B /* SDLFileManagerConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 880245A320F79C3400ED195B /* SDLFileManagerConfiguration.m */; }; + 8803DCEF22C2B84B00FBB7CE /* SDLBackgroundTaskManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 8803DCED22C2B84B00FBB7CE /* SDLBackgroundTaskManager.h */; }; + 8803DCF022C2B84B00FBB7CE /* SDLBackgroundTaskManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 8803DCEE22C2B84B00FBB7CE /* SDLBackgroundTaskManager.m */; }; 880D267A220DDD1000B3F496 /* SDLWeatherServiceDataSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 880D2679220DDD1000B3F496 /* SDLWeatherServiceDataSpec.m */; }; 880D267D220DE5DF00B3F496 /* SDLWeatherServiceManifest.h in Headers */ = {isa = PBXBuildFile; fileRef = 880D267B220DE5DF00B3F496 /* SDLWeatherServiceManifest.h */; settings = {ATTRIBUTES = (Public, ); }; }; 880D267E220DE5DF00B3F496 /* SDLWeatherServiceManifest.m in Sources */ = {isa = PBXBuildFile; fileRef = 880D267C220DE5DF00B3F496 /* SDLWeatherServiceManifest.m */; }; @@ -2892,6 +2894,8 @@ 756C62752289F11F008B57A2 /* SDLDynamicMenuUpdateRunScore.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLDynamicMenuUpdateRunScore.m; sourceTree = ""; }; 880245A220F79C3400ED195B /* SDLFileManagerConfiguration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLFileManagerConfiguration.h; sourceTree = ""; }; 880245A320F79C3400ED195B /* SDLFileManagerConfiguration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLFileManagerConfiguration.m; sourceTree = ""; }; + 8803DCED22C2B84B00FBB7CE /* SDLBackgroundTaskManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLBackgroundTaskManager.h; sourceTree = ""; }; + 8803DCEE22C2B84B00FBB7CE /* SDLBackgroundTaskManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLBackgroundTaskManager.m; sourceTree = ""; }; 880D2679220DDD1000B3F496 /* SDLWeatherServiceDataSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLWeatherServiceDataSpec.m; sourceTree = ""; }; 880D267B220DE5DF00B3F496 /* SDLWeatherServiceManifest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLWeatherServiceManifest.h; sourceTree = ""; }; 880D267C220DE5DF00B3F496 /* SDLWeatherServiceManifest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLWeatherServiceManifest.m; sourceTree = ""; }; @@ -4791,6 +4795,8 @@ 5D5934F61A85189500687FB9 /* Utilities */ = { isa = PBXGroup; children = ( + 8803DCED22C2B84B00FBB7CE /* SDLBackgroundTaskManager.h */, + 8803DCEE22C2B84B00FBB7CE /* SDLBackgroundTaskManager.m */, 97E26DEA1E807AD70074A3C7 /* SDLMutableDataQueue.h */, 97E26DEB1E807AD70074A3C7 /* SDLMutableDataQueue.m */, E9C32B831AB20B2900F283AF /* @categories */, @@ -6426,6 +6432,7 @@ 5D61FC511A84238C00846EE7 /* SDLButtonCapabilities.h in Headers */, 5D61FDE91A84238C00846EE7 /* SDLUnsubscribeButtonResponse.h in Headers */, 5D61FCD51A84238C00846EE7 /* SDLImageType.h in Headers */, + 8803DCEF22C2B84B00FBB7CE /* SDLBackgroundTaskManager.h in Headers */, 5D61FC2F1A84238C00846EE7 /* SDLAddCommandResponse.h in Headers */, 5D0C2A0020D9479B008B56CD /* SDLStreamingVideoLifecycleManager.h in Headers */, 5D61FD631A84238C00846EE7 /* SDLResetGlobalProperties.h in Headers */, @@ -7204,6 +7211,7 @@ 5D61FC5E1A84238C00846EE7 /* SDLChangeRegistrationResponse.m in Sources */, 5D8204231BCEA89A00D0A41B /* SDLFileManager.m in Sources */, 1EB59CC0202DA26000343A61 /* SDLSeatControlData.m in Sources */, + 8803DCF022C2B84B00FBB7CE /* SDLBackgroundTaskManager.m in Sources */, 5D61FC7D1A84238C00846EE7 /* SDLDeleteInteractionChoiceSetResponse.m in Sources */, DAC572661D10C5640004288B /* CGPoint_Util.m in Sources */, 5D00AC681F140F0A004000D9 /* SDLSystemCapabilityType.m in Sources */, diff --git a/SmartDeviceLink/SDLBackgroundTaskManager.h b/SmartDeviceLink/SDLBackgroundTaskManager.h new file mode 100644 index 000000000..0732b6fda --- /dev/null +++ b/SmartDeviceLink/SDLBackgroundTaskManager.h @@ -0,0 +1,44 @@ +// +// SDLBackgroundTaskManager.h +// SmartDeviceLink +// +// Created by Nicole on 6/25/19. +// Copyright © 2019 smartdevicelink. All rights reserved. +// + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Class for managing a background task. + */ +@interface SDLBackgroundTaskManager : NSObject + +- (instancetype)init NS_UNAVAILABLE; + +/** + * Convenience init for starting a background task with a specific name. + * + * @param backgroundTaskName The name for the background task + * @return A SDLBackgroundTaskManager object + */ +- (instancetype)initWithBackgroundTaskName:(NSString *)backgroundTaskName; + +/** + * Starts a background task that allows the app to establish a session while app is backgrounded. If the app is not currently backgrounded, the background task will remain dormant until the app moves to the background. + */ +- (void)startBackgroundTask; + +/** + * Cleans up a background task when it is stopped. This should be called when: + * + * 1. The app has established a session. + * 2. The system has called the `expirationHandler` for the background task. The system may kill the app if the background task is not ended when `expirationHandler` is called. + */ +- (void)endBackgroundTask; + +@end + +NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLBackgroundTaskManager.m b/SmartDeviceLink/SDLBackgroundTaskManager.m new file mode 100644 index 000000000..2109a40cd --- /dev/null +++ b/SmartDeviceLink/SDLBackgroundTaskManager.m @@ -0,0 +1,68 @@ +// +// SDLBackgroundTaskManager.m +// SmartDeviceLink +// +// Created by Nicole on 6/25/19. +// Copyright © 2019 smartdevicelink. All rights reserved. +// + +#import "SDLBackgroundTaskManager.h" + +#import "SDLLogMacros.h" + + +NS_ASSUME_NONNULL_BEGIN + +@interface SDLBackgroundTaskManager () +@property (copy, nonatomic) NSString *backgroundTaskName; +@property (assign, nonatomic) UIBackgroundTaskIdentifier currentBackgroundTaskId; + +@end + +@implementation SDLBackgroundTaskManager + +- (instancetype)initWithBackgroundTaskName:(NSString *)backgroundTaskName { + SDLLogV(@"SDLBackgroundTaskManager init with name %@", backgroundTaskName); + self = [super init]; + if (!self) { + return nil; + } + + _backgroundTaskName = backgroundTaskName; + + return self; +} + +- (void)startBackgroundTask { + if (self.currentBackgroundTaskId != UIBackgroundTaskInvalid) { + SDLLogV(@"The %@ background task is already running.", self.backgroundTaskName); + return; + } + + __weak typeof(self) weakself = self; + self.currentBackgroundTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithName:self.backgroundTaskName expirationHandler:^{ + SDLLogD(@"The %@ background task expired", self.backgroundTaskName); + [weakself endBackgroundTask]; + }]; + + SDLLogD(@"The %@ background task started with id: %lu", self.backgroundTaskName, (unsigned long)self.currentBackgroundTaskId); +} + +- (void)endBackgroundTask { + if (self.currentBackgroundTaskId == UIBackgroundTaskInvalid) { + SDLLogV(@"Background task already ended. Returning..."); + return; + } + + SDLLogD(@"Ending background task with id: %lu", (unsigned long)self.currentBackgroundTaskId); + [[UIApplication sharedApplication] endBackgroundTask:self.currentBackgroundTaskId]; + self.currentBackgroundTaskId = UIBackgroundTaskInvalid; +} + +- (void)dealloc { + [self endBackgroundTask]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLIAPTransport.m b/SmartDeviceLink/SDLIAPTransport.m index 3422ff39f..d67b2f11e 100644 --- a/SmartDeviceLink/SDLIAPTransport.m +++ b/SmartDeviceLink/SDLIAPTransport.m @@ -15,12 +15,10 @@ #import "SDLIAPDataSession.h" #import "SDLIAPDataSessionDelegate.h" #import "SDLLogMacros.h" -#import "SDLTimer.h" #import NS_ASSUME_NONNULL_BEGIN -NSString *const BackgroundTaskName = @"com.sdl.transport.iap.backgroundTask"; int const CreateSessionRetries = 3; @interface SDLIAPTransport () @@ -30,7 +28,6 @@ @interface SDLIAPTransport () @@ -88,6 +90,7 @@ @interface SDLLifecycleManager () #import #import @@ -97,7 +96,6 @@ - (instancetype)initWithTransport:(id)transport delegate:(id