diff --git a/UnitTests/MPBackendControllerTests.m b/UnitTests/MPBackendControllerTests.m index ca36d0ca9..c6373cbaa 100644 --- a/UnitTests/MPBackendControllerTests.m +++ b/UnitTests/MPBackendControllerTests.m @@ -17,7 +17,6 @@ #import "MPKitConfiguration.h" #import "MParticleSwift.h" #import "MPBaseTestCase.h" -#import "MPDevice.h" #import "MPLaunchInfo.h" #if TARGET_OS_IOS == 1 diff --git a/UnitTests/MPDeviceTests.m b/UnitTests/MPDeviceTests.m index 8b6fe4db5..af68a01e1 100644 --- a/UnitTests/MPDeviceTests.m +++ b/UnitTests/MPDeviceTests.m @@ -1,10 +1,12 @@ #import #import -#import "MPDevice.h" #import "mParticle.h" #import "MPIConstants.h" #import "MParticleSwift.h" - +#if TARGET_OS_IOS == 1 + #import + #import +#endif @interface MParticle () @property (nonatomic, strong, readonly) MPStateMachine_PRIVATE *stateMachine; @@ -19,23 +21,20 @@ @interface MPDeviceTests : XCTestCase @implementation MPDeviceTests - (void)testTelephonyRadioAccessTechnology { -#if TARGET_OS_IOS == 1 - CTTelephonyNetworkInfo *mockTelephonyNetworkInfo = OCMPartialMock([[CTTelephonyNetworkInfo alloc] init]); - [[[(id)mockTelephonyNetworkInfo stub] andReturn:@"foo"] currentRadioAccessTechnology]; - MPDevice *device = [[MPDevice alloc] init]; - [device setValue:mockTelephonyNetworkInfo forKey:@"telephonyNetworkInfo"]; +#if TARGET_OS_IOS == 1 && !MPARTICLE_LOCATION_DISABLE + MPDevice *device = [[MPDevice alloc] initWithStateMachine:[MParticle sharedInstance].stateMachine userDefaults:[MPUserDefaults standardUserDefaultsWithStateMachine:[MParticle sharedInstance].stateMachine backendController:[MParticle sharedInstance].backendController identity:[MParticle sharedInstance].identity] identity:[MParticle sharedInstance].identity]; NSString *technology = device.radioAccessTechnology; XCTAssertEqualObjects(technology, @"None"); #endif } - (void)testDictionaryDescription { -#if TARGET_OS_IOS == 1 +#if TARGET_OS_IOS == 1 && !MPARTICLE_LOCATION_DISABLE MPUserDefaults *userDefaults = [MPUserDefaults standardUserDefaultsWithStateMachine:[MParticle sharedInstance].stateMachine backendController:[MParticle sharedInstance].backendController identity:[MParticle sharedInstance].identity]; NSData *testDeviceToken = [@"<000000000000000000000000000000>" dataUsingEncoding:NSUTF8StringEncoding]; userDefaults[kMPDeviceTokenKey] = testDeviceToken; - MPDevice *device = [[MPDevice alloc] init]; + MPDevice *device = [[MPDevice alloc] initWithStateMachine:[MParticle sharedInstance].stateMachine userDefaults:[MPUserDefaults standardUserDefaultsWithStateMachine:[MParticle sharedInstance].stateMachine backendController:[MParticle sharedInstance].backendController identity:[MParticle sharedInstance].identity] identity:[MParticle sharedInstance].identity]; NSDictionary *testDictionary = device.dictionaryRepresentation; XCTAssertEqualObjects(testDictionary[@"dll"], @"en"); XCTAssertEqualObjects(testDictionary[@"dlc"], @"US"); diff --git a/UnitTests/MPNetworkCommunicationTests.m b/UnitTests/MPNetworkCommunicationTests.m index 5c4cfa5f3..d6648789c 100644 --- a/UnitTests/MPNetworkCommunicationTests.m +++ b/UnitTests/MPNetworkCommunicationTests.m @@ -11,7 +11,6 @@ #import "MPPersistenceController.h" #import "MPURL.h" #import "MPStateMachine.h" -#import "MPDevice.h" #import "MParticleSwift.h" #import "MPIConstants.h" diff --git a/UnitTests/MPUploadBuilderTests.m b/UnitTests/MPUploadBuilderTests.m index 75b240a26..d6811a1e6 100644 --- a/UnitTests/MPUploadBuilderTests.m +++ b/UnitTests/MPUploadBuilderTests.m @@ -9,7 +9,6 @@ #import "MPIntegrationAttributes.h" #import "MPPersistenceController.h" #import "MPBaseTestCase.h" -#import "MPDevice.h" #import "mParticle.h" #import "MParticleSwift.h" diff --git a/UnitTests/MParticleTests.m b/UnitTests/MParticleTests.m index 8c4377a11..6db62f261 100644 --- a/UnitTests/MParticleTests.m +++ b/UnitTests/MParticleTests.m @@ -8,7 +8,6 @@ #import "MPURLRequestBuilder.h" #import "MPPersistenceController.h" #import "MPURL.h" -#import "MPDevice.h" #import "MPKitContainer.h" #import "MPKitTestClassSideloaded.h" #import "MPKitTestClassNoStartImmediately.h" @@ -826,7 +825,7 @@ - (void)testSetATTStatusNotDetermined { XCTAssertEqual(instance.stateMachine.attAuthorizationStatus.intValue, MPATTAuthorizationStatusNotDetermined); XCTAssert(instance.stateMachine.attAuthorizationTimestamp); - MPDevice *device = [[MPDevice alloc] init]; + MPDevice *device = [[MPDevice alloc] initWithStateMachine:[MParticle sharedInstance].stateMachine userDefaults:[MPUserDefaults standardUserDefaultsWithStateMachine:[MParticle sharedInstance].stateMachine backendController:[MParticle sharedInstance].backendController identity:[MParticle sharedInstance].identity] identity:[MParticle sharedInstance].identity]; NSDictionary *deviceDict = [device dictionaryRepresentation]; XCTAssertEqualObjects(deviceDict[kMPATT], @"not_determined"); @@ -854,7 +853,7 @@ - (void)testSetATTStatusRestricted { XCTAssertEqual(instance.stateMachine.attAuthorizationStatus.intValue, MPATTAuthorizationStatusRestricted); XCTAssert(instance.stateMachine.attAuthorizationTimestamp); - MPDevice *device = [[MPDevice alloc] init]; + MPDevice *device = [[MPDevice alloc] initWithStateMachine:[MParticle sharedInstance].stateMachine userDefaults:[MPUserDefaults standardUserDefaultsWithStateMachine:[MParticle sharedInstance].stateMachine backendController:[MParticle sharedInstance].backendController identity:[MParticle sharedInstance].identity] identity:[MParticle sharedInstance].identity]; NSDictionary *deviceDict = [device dictionaryRepresentation]; XCTAssertEqualObjects(deviceDict[kMPATT], @"restricted"); @@ -882,7 +881,7 @@ - (void)testSetATTStatusDenied { XCTAssertEqual(instance.stateMachine.attAuthorizationStatus.intValue, MPATTAuthorizationStatusDenied); XCTAssert(instance.stateMachine.attAuthorizationTimestamp); - MPDevice *device = [[MPDevice alloc] init]; + MPDevice *device = [[MPDevice alloc] initWithStateMachine:[MParticle sharedInstance].stateMachine userDefaults:[MPUserDefaults standardUserDefaultsWithStateMachine:[MParticle sharedInstance].stateMachine backendController:[MParticle sharedInstance].backendController identity:[MParticle sharedInstance].identity] identity:[MParticle sharedInstance].identity]; NSDictionary *deviceDict = [device dictionaryRepresentation]; XCTAssertEqualObjects(deviceDict[kMPATT], @"denied"); @@ -910,7 +909,7 @@ - (void)testSetATTStatusAuthorized { XCTAssertEqual(instance.stateMachine.attAuthorizationStatus.intValue, MPATTAuthorizationStatusAuthorized); XCTAssert(instance.stateMachine.attAuthorizationTimestamp); - MPDevice *device = [[MPDevice alloc] init]; + MPDevice *device = [[MPDevice alloc] initWithStateMachine:[MParticle sharedInstance].stateMachine userDefaults:[MPUserDefaults standardUserDefaultsWithStateMachine:[MParticle sharedInstance].stateMachine backendController:[MParticle sharedInstance].backendController identity:[MParticle sharedInstance].identity] identity:[MParticle sharedInstance].identity]; NSDictionary *deviceDict = [device dictionaryRepresentation]; XCTAssertEqualObjects(deviceDict[kMPATT], @"authorized"); @@ -939,7 +938,7 @@ - (void)testSetATTStatusWithTimestamp { XCTAssertEqual(instance.stateMachine.attAuthorizationStatus.intValue, MPATTAuthorizationStatusAuthorized); XCTAssertEqual(instance.stateMachine.attAuthorizationTimestamp.doubleValue, testTimestamp.doubleValue); - MPDevice *device = [[MPDevice alloc] init]; + MPDevice *device = [[MPDevice alloc] initWithStateMachine:[MParticle sharedInstance].stateMachine userDefaults:[MPUserDefaults standardUserDefaultsWithStateMachine:[MParticle sharedInstance].stateMachine backendController:[MParticle sharedInstance].backendController identity:[MParticle sharedInstance].identity] identity:[MParticle sharedInstance].identity]; NSDictionary *deviceDict = [device dictionaryRepresentation]; XCTAssertEqualObjects(deviceDict[kMPATT], @"authorized"); @@ -967,7 +966,7 @@ - (void)testSetATTStatusRemoveIDFA { XCTAssertEqual(instance.stateMachine.attAuthorizationStatus.intValue, MPATTAuthorizationStatusDenied); XCTAssert(instance.stateMachine.attAuthorizationTimestamp); - MPDevice *device = [[MPDevice alloc] init]; + MPDevice *device = [[MPDevice alloc] initWithStateMachine:[MParticle sharedInstance].stateMachine userDefaults:[MPUserDefaults standardUserDefaultsWithStateMachine:[MParticle sharedInstance].stateMachine backendController:[MParticle sharedInstance].backendController identity:[MParticle sharedInstance].identity] identity:[MParticle sharedInstance].identity]; NSDictionary *deviceDict = [device dictionaryRepresentation]; XCTAssertEqualObjects(deviceDict[kMPATT], @"denied"); diff --git a/mParticle-Apple-SDK.xcodeproj/project.pbxproj b/mParticle-Apple-SDK.xcodeproj/project.pbxproj index 0978455ef..9870a76cf 100644 --- a/mParticle-Apple-SDK.xcodeproj/project.pbxproj +++ b/mParticle-Apple-SDK.xcodeproj/project.pbxproj @@ -160,7 +160,6 @@ 53A79BCE29CDFB2000E7489F /* NSDictionary+MPCaseInsensitive.m in Sources */ = {isa = PBXBuildFile; fileRef = 53A79B0929CDFB1F00E7489F /* NSDictionary+MPCaseInsensitive.m */; }; 53A79BD229CDFB2000E7489F /* MPApplication.m in Sources */ = {isa = PBXBuildFile; fileRef = 53A79B0D29CDFB1F00E7489F /* MPApplication.m */; }; 53A79BD729CDFB2000E7489F /* MPUploadBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 53A79B1229CDFB1F00E7489F /* MPUploadBuilder.m */; }; - 53A79BDA29CDFB2000E7489F /* MPDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = 53A79B1529CDFB1F00E7489F /* MPDevice.m */; }; 53A79BDC29CDFB2000E7489F /* MPLaunchInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 53A79B1729CDFB1F00E7489F /* MPLaunchInfo.h */; }; 53A79BDF29CDFB2000E7489F /* MPMessageBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 53A79B1A29CDFB1F00E7489F /* MPMessageBuilder.h */; }; 53A79BE329CDFB2000E7489F /* MPBracket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53A79B1E29CDFB1F00E7489F /* MPBracket.cpp */; }; @@ -168,7 +167,6 @@ 53A79BE929CDFB2000E7489F /* MPApplication.h in Headers */ = {isa = PBXBuildFile; fileRef = 53A79B2429CDFB1F00E7489F /* MPApplication.h */; settings = {ATTRIBUTES = (Public, ); }; }; 53A79BEB29CDFB2000E7489F /* NSNumber+MPFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53A79B2629CDFB1F00E7489F /* NSNumber+MPFormatter.swift */; }; 53A79BEE29CDFB2000E7489F /* MPLaunchInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 53A79B2929CDFB1F00E7489F /* MPLaunchInfo.m */; }; - 53A79BF029CDFB2000E7489F /* MPDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 53A79B2B29CDFB1F00E7489F /* MPDevice.h */; }; 53A79BF129CDFB2000E7489F /* MPBracket.h in Headers */ = {isa = PBXBuildFile; fileRef = 53A79B2C29CDFB1F00E7489F /* MPBracket.h */; }; 53A79BF329CDFB2000E7489F /* MPCustomModulePreference.h in Headers */ = {isa = PBXBuildFile; fileRef = 53A79B2F29CDFB1F00E7489F /* MPCustomModulePreference.h */; }; 53A79BF429CDFB2000E7489F /* MPCustomModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 53A79B3029CDFB1F00E7489F /* MPCustomModule.h */; }; @@ -364,7 +362,6 @@ 53A79D4129CE23F700E7489F /* MPDatabaseMigrationController.h in Headers */ = {isa = PBXBuildFile; fileRef = 53A79ABA29CDFB1E00E7489F /* MPDatabaseMigrationController.h */; }; 53A79D4329CE23F700E7489F /* MParticleUserNotification.h in Headers */ = {isa = PBXBuildFile; fileRef = 53A79ABD29CDFB1E00E7489F /* MParticleUserNotification.h */; }; 53A79D4529CE23F700E7489F /* MPForwardQueueItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 53A79B5229CDFB1F00E7489F /* MPForwardQueueItem.h */; }; - 53A79D4629CE23F700E7489F /* MPDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 53A79B2B29CDFB1F00E7489F /* MPDevice.h */; }; 53A79D4729CE23F700E7489F /* MPAttributeProjection.h in Headers */ = {isa = PBXBuildFile; fileRef = 53A79B4E29CDFB1F00E7489F /* MPAttributeProjection.h */; }; 53A79D4829CE23F700E7489F /* MPConsentSerialization.h in Headers */ = {isa = PBXBuildFile; fileRef = 53A79AFA29CDFB1F00E7489F /* MPConsentSerialization.h */; }; 53A79D4929CE23F700E7489F /* MPConsentKitFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 53A79AFC29CDFB1F00E7489F /* MPConsentKitFilter.h */; }; @@ -392,7 +389,6 @@ 53A79D6329CE23F700E7489F /* MPMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 53A79ACB29CDFB1E00E7489F /* MPMessage.h */; }; 53A79D6529CE23F700E7489F /* MPConnector.h in Headers */ = {isa = PBXBuildFile; fileRef = 53A79AB529CDFB1E00E7489F /* MPConnector.h */; }; 53A79D6729CE23F700E7489F /* MPForwardQueueParameters.m in Sources */ = {isa = PBXBuildFile; fileRef = 53A79B5129CDFB1F00E7489F /* MPForwardQueueParameters.m */; }; - 53A79D6829CE23F700E7489F /* MPDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = 53A79B1529CDFB1F00E7489F /* MPDevice.m */; }; 53A79D6929CE23F700E7489F /* NSDictionary+MPCaseInsensitive.m in Sources */ = {isa = PBXBuildFile; fileRef = 53A79B0929CDFB1F00E7489F /* NSDictionary+MPCaseInsensitive.m */; }; 53A79D6C29CE23F700E7489F /* MPURLRequestBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 53A79AB229CDFB1E00E7489F /* MPURLRequestBuilder.m */; }; 53A79D6D29CE23F700E7489F /* MPCustomModulePreference.m in Sources */ = {isa = PBXBuildFile; fileRef = 53A79B3129CDFB1F00E7489F /* MPCustomModulePreference.m */; }; @@ -499,6 +495,8 @@ D3CEDAC92CA2F214001B32DF /* MPLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3CEDAC72CA2F214001B32DF /* MPLogger.swift */; }; D3CEDACB2CB027E1001B32DF /* MPConvertJS.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3CEDACA2CB027E1001B32DF /* MPConvertJS.swift */; }; D3CEDACC2CB027E1001B32DF /* MPConvertJS.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3CEDACA2CB027E1001B32DF /* MPConvertJS.swift */; }; + D3DE316B2D5261FC00CC537F /* MPDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3DE316A2D5261F700CC537F /* MPDevice.swift */; }; + D3DE316C2D5261FC00CC537F /* MPDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3DE316A2D5261F700CC537F /* MPDevice.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -597,7 +595,6 @@ 53A79B0929CDFB1F00E7489F /* NSDictionary+MPCaseInsensitive.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+MPCaseInsensitive.m"; sourceTree = ""; }; 53A79B0D29CDFB1F00E7489F /* MPApplication.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPApplication.m; sourceTree = ""; }; 53A79B1229CDFB1F00E7489F /* MPUploadBuilder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPUploadBuilder.m; sourceTree = ""; }; - 53A79B1529CDFB1F00E7489F /* MPDevice.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPDevice.m; sourceTree = ""; }; 53A79B1729CDFB1F00E7489F /* MPLaunchInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPLaunchInfo.h; sourceTree = ""; }; 53A79B1A29CDFB1F00E7489F /* MPMessageBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPMessageBuilder.h; sourceTree = ""; }; 53A79B1E29CDFB1F00E7489F /* MPBracket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MPBracket.cpp; sourceTree = ""; }; @@ -605,7 +602,6 @@ 53A79B2429CDFB1F00E7489F /* MPApplication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPApplication.h; sourceTree = ""; }; 53A79B2629CDFB1F00E7489F /* NSNumber+MPFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSNumber+MPFormatter.swift"; sourceTree = ""; }; 53A79B2929CDFB1F00E7489F /* MPLaunchInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPLaunchInfo.m; sourceTree = ""; }; - 53A79B2B29CDFB1F00E7489F /* MPDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPDevice.h; sourceTree = ""; }; 53A79B2C29CDFB1F00E7489F /* MPBracket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPBracket.h; sourceTree = ""; }; 53A79B2F29CDFB1F00E7489F /* MPCustomModulePreference.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPCustomModulePreference.h; sourceTree = ""; }; 53A79B3029CDFB1F00E7489F /* MPCustomModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPCustomModule.h; sourceTree = ""; }; @@ -779,6 +775,7 @@ D3CEDAC22C9DAC25001B32DF /* MPDateFormatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPDateFormatter.swift; sourceTree = ""; }; D3CEDAC72CA2F214001B32DF /* MPLogger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPLogger.swift; sourceTree = ""; }; D3CEDACA2CB027E1001B32DF /* MPConvertJS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPConvertJS.swift; sourceTree = ""; }; + D3DE316A2D5261F700CC537F /* MPDevice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPDevice.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -1008,14 +1005,13 @@ 53A79B0D29CDFB1F00E7489F /* MPApplication.m */, D3961CDD2CC0B7E4003B3194 /* NSString+MPPercentEscape.swift */, 53A79B1229CDFB1F00E7489F /* MPUploadBuilder.m */, - 53A79B1529CDFB1F00E7489F /* MPDevice.m */, 53A79B1729CDFB1F00E7489F /* MPLaunchInfo.h */, 53A79B1A29CDFB1F00E7489F /* MPMessageBuilder.h */, 53A79B1E29CDFB1F00E7489F /* MPBracket.cpp */, 53A79B2329CDFB1F00E7489F /* MPUploadBuilder.h */, 53A79B2629CDFB1F00E7489F /* NSNumber+MPFormatter.swift */, 53A79B2929CDFB1F00E7489F /* MPLaunchInfo.m */, - 53A79B2B29CDFB1F00E7489F /* MPDevice.h */, + D3DE316A2D5261F700CC537F /* MPDevice.swift */, 53A79B2C29CDFB1F00E7489F /* MPBracket.h */, 53FDD1BC2AE871AF003D5FA1 /* MPIHasher.swift */, 534C11B52D08F53D00466F71 /* MPUserAttributeChange.swift */, @@ -1340,7 +1336,6 @@ 53A79B8529CDFB2000E7489F /* MPDatabaseMigrationController.h in Headers */, 53A79B8729CDFB2000E7489F /* MParticleUserNotification.h in Headers */, 53A79C1029CDFB2100E7489F /* MPForwardQueueItem.h in Headers */, - 53A79BF029CDFB2000E7489F /* MPDevice.h in Headers */, 53A79C0C29CDFB2100E7489F /* MPAttributeProjection.h in Headers */, 53A79BC229CDFB2000E7489F /* MPConsentSerialization.h in Headers */, 53A79BC429CDFB2000E7489F /* MPConsentKitFilter.h in Headers */, @@ -1430,7 +1425,6 @@ 53A79D4129CE23F700E7489F /* MPDatabaseMigrationController.h in Headers */, 53A79D4329CE23F700E7489F /* MParticleUserNotification.h in Headers */, 53A79D4529CE23F700E7489F /* MPForwardQueueItem.h in Headers */, - 53A79D4629CE23F700E7489F /* MPDevice.h in Headers */, 53A79D4729CE23F700E7489F /* MPAttributeProjection.h in Headers */, 53A79D4829CE23F700E7489F /* MPConsentSerialization.h in Headers */, 53A79D4929CE23F700E7489F /* MPConsentKitFilter.h in Headers */, @@ -1691,7 +1685,6 @@ buildActionMask = 2147483647; files = ( 53A79C0F29CDFB2100E7489F /* MPForwardQueueParameters.m in Sources */, - 53A79BDA29CDFB2000E7489F /* MPDevice.m in Sources */, 53A79BCE29CDFB2000E7489F /* NSDictionary+MPCaseInsensitive.m in Sources */, 53A79B7E29CDFB2000E7489F /* MPURLRequestBuilder.m in Sources */, 53A79BF529CDFB2000E7489F /* MPCustomModulePreference.m in Sources */, @@ -1771,6 +1764,7 @@ 53A79C0429CDFB2100E7489F /* MPCommerceEventInstruction.m in Sources */, 53A79B9029CDFB2000E7489F /* MPDataModelAbstract.m in Sources */, 53FDD1BD2AE871AF003D5FA1 /* MPIHasher.swift in Sources */, + D3DE316B2D5261FC00CC537F /* MPDevice.swift in Sources */, 53A79BBD29CDFB2000E7489F /* MPBackendController.m in Sources */, 53A79C1B29CDFB2100E7489F /* MPForwardQueueItem.m in Sources */, 53A79C1629CDFB2100E7489F /* MPEventProjection.mm in Sources */, @@ -1862,7 +1856,6 @@ buildActionMask = 2147483647; files = ( 53A79D6729CE23F700E7489F /* MPForwardQueueParameters.m in Sources */, - 53A79D6829CE23F700E7489F /* MPDevice.m in Sources */, 53A79D6929CE23F700E7489F /* NSDictionary+MPCaseInsensitive.m in Sources */, 53A79D6C29CE23F700E7489F /* MPURLRequestBuilder.m in Sources */, 53A79D6D29CE23F700E7489F /* MPCustomModulePreference.m in Sources */, @@ -1942,6 +1935,7 @@ 53A79DB129CE23F700E7489F /* MPTransactionAttributes.m in Sources */, 53A79DB329CE23F700E7489F /* MPCommerceEventInstruction.m in Sources */, 53A79DB429CE23F700E7489F /* MPDataModelAbstract.m in Sources */, + D3DE316C2D5261FC00CC537F /* MPDevice.swift in Sources */, 53FDD1BE2AE871AF003D5FA1 /* MPIHasher.swift in Sources */, 53A79DB529CE23F700E7489F /* MPBackendController.m in Sources */, 53A79DB629CE23F700E7489F /* MPForwardQueueItem.m in Sources */, diff --git a/mParticle-Apple-SDK/Data Model/MPSession.m b/mParticle-Apple-SDK/Data Model/MPSession.m index b8ce8d475..341f69cdd 100644 --- a/mParticle-Apple-SDK/Data Model/MPSession.m +++ b/mParticle-Apple-SDK/Data Model/MPSession.m @@ -2,7 +2,6 @@ #import "MPIConstants.h" #import "MPPersistenceController.h" #import "MPApplication.h" -#import "MPDevice.h" NSString *const sessionUUIDKey = @"sessionId"; diff --git a/mParticle-Apple-SDK/Identity/MPIdentityApi.m b/mParticle-Apple-SDK/Identity/MPIdentityApi.m index d0041f24b..daf470c0b 100644 --- a/mParticle-Apple-SDK/Identity/MPIdentityApi.m +++ b/mParticle-Apple-SDK/Identity/MPIdentityApi.m @@ -13,7 +13,6 @@ #import "MPEnums.h" #import "MPILogger.h" #import "MPKitContainer.h" -#import "MPDevice.h" #import "MPUpload.h" #import "MParticleSwift.h" @@ -357,7 +356,7 @@ - (MParticleUser *)getUser:(NSNumber *)mpId { } - (NSString *)deviceApplicationStamp { - MPDevice *device = [[MPDevice alloc] init]; + MPDevice *device = [[MPDevice alloc] initWithStateMachine:[MParticle sharedInstance].stateMachine userDefaults:[MPUserDefaults standardUserDefaultsWithStateMachine:[MParticle sharedInstance].stateMachine backendController:[MParticle sharedInstance].backendController identity:[MParticle sharedInstance].identity] identity:[MParticle sharedInstance].identity]; return device.deviceIdentifier; } diff --git a/mParticle-Apple-SDK/Identity/MPIdentityApiRequest.m b/mParticle-Apple-SDK/Identity/MPIdentityApiRequest.m index b4e4ed1b2..8d24984e2 100644 --- a/mParticle-Apple-SDK/Identity/MPIdentityApiRequest.m +++ b/mParticle-Apple-SDK/Identity/MPIdentityApiRequest.m @@ -3,7 +3,6 @@ // #import "MPIdentityApiRequest.h" -#import "MPDevice.h" #import "MPNotificationController.h" #import "MPIConstants.h" #import "MPStateMachine.h" diff --git a/mParticle-Apple-SDK/Identity/MPIdentityDTO.m b/mParticle-Apple-SDK/Identity/MPIdentityDTO.m index b64aafbb2..85e9d2733 100644 --- a/mParticle-Apple-SDK/Identity/MPIdentityDTO.m +++ b/mParticle-Apple-SDK/Identity/MPIdentityDTO.m @@ -4,7 +4,6 @@ #import "MPIdentityDTO.h" #import "mParticle.h" -#import "MPDevice.h" #import "MPNotificationController.h" #import "MPPersistenceController.h" #import "MPConsumerInfo.h" @@ -14,6 +13,7 @@ @interface MParticle () @property (nonatomic, strong, readonly) MPPersistenceController_PRIVATE *persistenceController; @property (nonatomic, strong, readonly) MPStateMachine_PRIVATE *stateMachine; +@property (nonatomic, strong, nonnull) MPBackendController_PRIVATE *backendController; @end @@ -59,8 +59,8 @@ - (instancetype)initWithIdentityApiRequest:(MPIdentityApiRequest *)apiRequest { _previousMPID = [MPPersistenceController_PRIVATE mpId].stringValue; } - MPDevice *device = [[MPDevice alloc] init]; - + MPDevice *device = [[MPDevice alloc] initWithStateMachine:[MParticle sharedInstance].stateMachine userDefaults:[MPUserDefaults standardUserDefaultsWithStateMachine:[MParticle sharedInstance].stateMachine backendController:[MParticle sharedInstance].backendController identity:[MParticle sharedInstance].identity] identity:[MParticle sharedInstance].identity]; + NSString *vendorId = device.vendorId; if (vendorId) { _knownIdentities.vendorId = vendorId; diff --git a/mParticle-Apple-SDK/MPBackendController.m b/mParticle-Apple-SDK/MPBackendController.m index 46b282598..95a97ff85 100644 --- a/mParticle-Apple-SDK/MPBackendController.m +++ b/mParticle-Apple-SDK/MPBackendController.m @@ -22,7 +22,6 @@ #import "MPKitContainer.h" #import "MPURLRequestBuilder.h" #import "MPListenerController.h" -#import "MPDevice.h" #import "MPIdentityCaching.h" #import "MParticleSwift.h" #import "MPLaunchInfo.h" @@ -878,7 +877,9 @@ - (void)beginSessionWithIsManual:(BOOL)isManual date:(NSDate *)date { _session.appInfo = [[[MPApplication_PRIVATE alloc] init] dictionaryRepresentation]; } if (!_session.deviceInfo) { - _session.deviceInfo = [[[MPDevice alloc] init] dictionaryRepresentationWithMpid:mpId]; + MPDevice *device = [[MPDevice alloc] initWithStateMachine:[MParticle sharedInstance].stateMachine userDefaults:[MPUserDefaults standardUserDefaultsWithStateMachine:[MParticle sharedInstance].stateMachine backendController:[MParticle sharedInstance].backendController identity:[MParticle sharedInstance].identity] identity:[MParticle sharedInstance].identity]; + + _session.deviceInfo = [device dictionaryRepresentationWithMpid:mpId]; } [persistence saveSession:_session]; diff --git a/mParticle-Apple-SDK/MPConstants.swift b/mParticle-Apple-SDK/MPConstants.swift index 605029072..bd0244060 100644 --- a/mParticle-Apple-SDK/MPConstants.swift +++ b/mParticle-Apple-SDK/MPConstants.swift @@ -54,6 +54,26 @@ struct MessageKeys { static let kMPDataPlanVersionKey = "v" } +struct PushNotifications { + static let kMPDeviceTokenKey = "to" + static let kMPPushStatusKey = "r" + static let kMPPushMessageTypeKey = "t" + static let kMPPushMessageReceived = "received" + static let kMPPushMessageAction = "action" + static let kMPPushMessageSent = "sent" + static let kMPPushMessageProviderKey = "n" + static let kMPPushMessageProviderValue = "apn" + static let kMPPushMessagePayloadKey = "pay" + static let kMPPushNotificationStateKey = "as" + static let kMPPushNotificationStateNotRunning = "not_running" + static let kMPPushNotificationStateBackground = "background" + static let kMPPushNotificationStateForeground = "foreground" + static let kMPPushNotificationActionIdentifierKey = "aid" + static let kMPPushNotificationBehaviorKey = "bhv" + static let kMPPushNotificationActionTitleKey = "an" + static let kMPPushNotificationCategoryIdentifierKey = "acid" +} + struct RemoteConfig { static let kMPRemoteConfigExceptionHandlingModeKey = "cue" static let kMPRemoteConfigExceptionHandlingModeAppDefined = "appdefined" @@ -166,6 +186,40 @@ struct Notifications { static let kMPRemoteNotificationOldDeviceTokenKey = Notification.Name("MPRemoteNotificationOldDeviceTokenKey") } +struct Device { + static let kMPDeviceInformationKey = "di" + static let kMPDeviceBrandKey = "b" + static let kMPDeviceProductKey = "p" + static let kMPDeviceNameKey = "dn" + static let kMPDeviceAdvertiserIdKey = "aid" + static let kMPDeviceAppVendorIdKey = "vid" + static let kMPDeviceBuildIdKey = "bid" + static let kMPDeviceManufacturerKey = "dma" + static let kMPDevicePlatformKey = "dp" + static let kMPDeviceOSKey = "dosv" + static let kMPDeviceModelKey = "dmdl" + static let kMPScreenHeightKey = "dsh" + static let kMPScreenWidthKey = "dsw" + static let kMPDeviceLocaleCountryKey = "dlc" + static let kMPDeviceLocaleLanguageKey = "dll" + static let kMPNetworkCountryKey = "nc" + static let kMPNetworkCarrierKey = "nca" + static let kMPMobileNetworkCodeKey = "mnc" + static let kMPMobileCountryCodeKey = "mcc" + static let kMPTimezoneOffsetKey = "tz" + static let kMPTimezoneDescriptionKey = "tzn" + static let kMPDeviceJailbrokenKey = "jb" + static let kMPDeviceArchitectureKey = "arc" + static let kMPDeviceRadioKey = "dr" + static let kMPDeviceFloatingPointFormat = "%0.0f" + static let kMPDeviceSignerIdentityString = "signeridentity" + static let kMPDeviceIsTabletKey = "it" + static let kMPDeviceIdentifierKey = "deviceIdentifier" + static let kMPDeviceLimitAdTrackingKey = "lat" + static let kMPDeviceIsDaylightSavingTime = "idst" + static let kMPDeviceInvalidVendorId = "00000000-0000-0000-0000-000000000000" +} + struct Miscellaneous { static let kMPFirstSeenUser = "fsu" static let kMPLastSeenUser = "lsu" @@ -179,4 +233,76 @@ struct Miscellaneous { static let kMPLastUploadSettingsUserDefaultsKey = "lastUploadSettings" static let CONFIG_REQUESTS_DEFAULT_EXPIRATION_AGE = 5.0*60 static let CONFIG_REQUESTS_MAX_EXPIRATION_AGE = 60*60*24.0 + static let kMPDeviceTokenTypeKey = "tot" + static let kMPATT = "atts" + static let kMPATTTimestamp = "attt" + static let kMPDeviceCydiaJailbrokenKey = "cydia" + +} + +/// User Identities +/// The identities in this enum are limited to end-user forms of identity. A new enum, MPIdentity, has been provided to cover all valid forms of identity supported by the mParticle Identity API (user identities and device identities) +@objc public enum MPUserIdentitySwift: Int { + case other = 0 + case customerId = 1 + case facebook = 2 + case twitter = 3 + case google = 4 + case microsoft = 5 + case yahoo = 6 + case email = 7 + case alias = 8 + case facebookCustomAudienceId = 9 + case other2 = 10 + case other3 = 11 + case other4 = 12 + case other5 = 13 + case other6 = 14 + case other7 = 15 + case other8 = 16 + case other9 = 17 + case other10 = 18 + case mobileNumber = 19 + case phoneNumber2 = 20 + case phoneNumber3 = 21 +} + +/// MP Identities +@objc public enum MPIdentitySwift: Int { + case other = 0 + case customerId = 1 + case facebook = 2 + case twitter = 3 + case google = 4 + case microsoft = 5 + case yahoo = 6 + case email = 7 + case alias = 8 + case facebookCustomAudienceId = 9 + case other2 = 10 + case other3 = 11 + case other4 = 12 + case other5 = 13 + case other6 = 14 + case other7 = 15 + case other8 = 16 + case other9 = 17 + case other10 = 18 + case mobileNumber = 19 + case phoneNumber2 = 20 + case phoneNumber3 = 21 + case iosAdvertiserId = 22 + case iosVendorId = 23 + case pushToken = 24 + case deviceApplicationStamp = 25 +} + +/** + @see https://developer.apple.com/documentation/apptrackingtransparency/attrackingmanager/authorizationstatus + */ +@objc public enum MPATTAuthorizationStatusSwift: Int { + case notDetermined = 0 + case restricted + case denied + case authorized } diff --git a/mParticle-Apple-SDK/MPIConstants.h b/mParticle-Apple-SDK/MPIConstants.h index bfe55f902..13a1f71c7 100644 --- a/mParticle-Apple-SDK/MPIConstants.h +++ b/mParticle-Apple-SDK/MPIConstants.h @@ -482,4 +482,36 @@ extern const NSInteger MAX_BYTES_PER_EVENT_CRASH; extern const NSInteger MAX_BYTES_PER_BATCH_CRASH; extern const NSInteger MAX_EVENTS_PER_BATCH; +// Device (Need these in objective C until the classes that use them are refactored to Swift) +extern NSString * _Nonnull const kMPDeviceInformationKey; +extern NSString * _Nonnull const kMPDeviceBrandKey; +extern NSString * _Nonnull const kMPDeviceProductKey; +extern NSString * _Nonnull const kMPDeviceNameKey; +extern NSString * _Nonnull const kMPDeviceAdvertiserIdKey; +extern NSString * _Nonnull const kMPDeviceAppVendorIdKey; +extern NSString * _Nonnull const kMPDeviceBuildIdKey; +extern NSString * _Nonnull const kMPDeviceManufacturerKey; +extern NSString * _Nonnull const kMPDevicePlatformKey; +extern NSString * _Nonnull const kMPDeviceOSKey; +extern NSString * _Nonnull const kMPDeviceModelKey; +extern NSString * _Nonnull const kMPScreenHeightKey; +extern NSString * _Nonnull const kMPScreenWidthKey; +extern NSString * _Nonnull const kMPDeviceLocaleCountryKey; +extern NSString * _Nonnull const kMPDeviceLocaleLanguageKey; +extern NSString * _Nonnull const kMPNetworkCountryKey; +extern NSString * _Nonnull const kMPNetworkCarrierKey; +extern NSString * _Nonnull const kMPMobileNetworkCodeKey; +extern NSString * _Nonnull const kMPMobileCountryCodeKey; +extern NSString * _Nonnull const kMPTimezoneOffsetKey; +extern NSString * _Nonnull const kMPTimezoneDescriptionKey; +extern NSString * _Nonnull const kMPDeviceJailbrokenKey; +extern NSString * _Nonnull const kMPDeviceArchitectureKey; +extern NSString * _Nonnull const kMPDeviceRadioKey; +extern NSString * _Nonnull const kMPDeviceFloatingPointFormat; +extern NSString * _Nonnull const kMPDeviceSignerIdentityString; +extern NSString * _Nonnull const kMPDeviceIsTabletKey; +extern NSString * _Nonnull const kMPDeviceIdentifierKey; +extern NSString * _Nonnull const kMPDeviceLimitAdTrackingKey; +extern NSString * _Nonnull const kMPDeviceIsDaylightSavingTime; +extern NSString * _Nonnull const kMPDeviceInvalidVendorId; #endif diff --git a/mParticle-Apple-SDK/MPIConstants.m b/mParticle-Apple-SDK/MPIConstants.m index 12172a504..65beba9ed 100644 --- a/mParticle-Apple-SDK/MPIConstants.m +++ b/mParticle-Apple-SDK/MPIConstants.m @@ -381,6 +381,38 @@ NSString *const kMPEventTypeStringProductRemoveFromWishlist = @"ProductRemoveFromWishlist"; NSString *const kMPEventTypeStringProductImpression = @"ProductImpression"; +// Device +NSString * const kMPDeviceInformationKey = @"di"; +NSString * const kMPDeviceBrandKey = @"b"; +NSString * const kMPDeviceProductKey = @"p"; +NSString * const kMPDeviceNameKey = @"dn"; +NSString * const kMPDeviceAdvertiserIdKey = @"aid"; +NSString * const kMPDeviceAppVendorIdKey = @"vid"; +NSString * const kMPDeviceBuildIdKey = @"bid"; +NSString * const kMPDeviceManufacturerKey = @"dma"; +NSString * const kMPDevicePlatformKey = @"dp"; +NSString * const kMPDeviceOSKey = @"dosv"; +NSString * const kMPDeviceModelKey = @"dmdl"; +NSString * const kMPScreenHeightKey = @"dsh"; +NSString * const kMPScreenWidthKey = @"dsw"; +NSString * const kMPDeviceLocaleCountryKey = @"dlc"; +NSString * const kMPDeviceLocaleLanguageKey = @"dll"; +NSString * const kMPNetworkCountryKey = @"nc"; +NSString * const kMPNetworkCarrierKey = @"nca"; +NSString * const kMPMobileNetworkCodeKey = @"mnc"; +NSString * const kMPMobileCountryCodeKey = @"mcc"; +NSString * const kMPTimezoneOffsetKey = @"tz"; +NSString * const kMPTimezoneDescriptionKey = @"tzn"; +NSString * const kMPDeviceJailbrokenKey = @"jb"; +NSString * const kMPDeviceArchitectureKey = @"arc"; +NSString * const kMPDeviceRadioKey = @"dr"; +NSString * const kMPDeviceFloatingPointFormat = @"%0.0f"; +NSString * const kMPDeviceSignerIdentityString = @"signeridentity"; +NSString * const kMPDeviceIsTabletKey = @"it"; +NSString * const kMPDeviceIdentifierKey = @"deviceIdentifier"; +NSString * const kMPDeviceLimitAdTrackingKey = @"lat"; +NSString * const kMPDeviceIsDaylightSavingTime = @"idst"; +NSString * const kMPDeviceInvalidVendorId = @"00000000-0000-0000-0000-000000000000"; // // Primitive data type constants // diff --git a/mParticle-Apple-SDK/MPStateMachine.m b/mParticle-Apple-SDK/MPStateMachine.m index 7863e8332..ca10c6287 100644 --- a/mParticle-Apple-SDK/MPStateMachine.m +++ b/mParticle-Apple-SDK/MPStateMachine.m @@ -2,7 +2,6 @@ #import "MPIConstants.h" #import "MPApplication.h" #import "MPCustomModule.h" -#import "MPDevice.h" #import #import "MPNotificationController.h" #import "MPILogger.h" @@ -676,7 +675,7 @@ - (void)configureRampPercentage:(NSNumber *)rampPercentage { BOOL dataRamped = YES; if (rampPercentage.integerValue != 0) { - MPDevice *device = [[MPDevice alloc] init]; + MPDevice *device = [[MPDevice alloc] initWithStateMachine:[MParticle sharedInstance].stateMachine userDefaults:[MPUserDefaults standardUserDefaultsWithStateMachine:[MParticle sharedInstance].stateMachine backendController:[MParticle sharedInstance].backendController identity:[MParticle sharedInstance].identity] identity:[MParticle sharedInstance].identity]; NSData *rampData = [device.deviceIdentifier dataUsingEncoding:NSUTF8StringEncoding]; uint64_t rampHash = [MPIHasher hashFNV1a:rampData]; diff --git a/mParticle-Apple-SDK/Network/MPNetworkCommunication.m b/mParticle-Apple-SDK/Network/MPNetworkCommunication.m index 408dfb0e7..c5d86e4a2 100644 --- a/mParticle-Apple-SDK/Network/MPNetworkCommunication.m +++ b/mParticle-Apple-SDK/Network/MPNetworkCommunication.m @@ -4,7 +4,6 @@ #import #import "MPConnector.h" #import "MPUpload.h" -#import "MPDevice.h" #import "MPApplication.h" #import "MPIConstants.h" #import "MPURLRequestBuilder.h" diff --git a/mParticle-Apple-SDK/Persistence/MPPersistenceController.mm b/mParticle-Apple-SDK/Persistence/MPPersistenceController.mm index befbb98f2..18ee2d7fd 100644 --- a/mParticle-Apple-SDK/Persistence/MPPersistenceController.mm +++ b/mParticle-Apple-SDK/Persistence/MPPersistenceController.mm @@ -17,7 +17,6 @@ #import #import "MPListenerProtocol.h" #import "MPKitFilter.h" -#import "MPDevice.h" #import "MPApplication.h" #import "MParticleSwift.h" #import "MParticleUserNotification.h" diff --git a/mParticle-Apple-SDK/Utils/MPDevice.h b/mParticle-Apple-SDK/Utils/MPDevice.h deleted file mode 100644 index c1a127aca..000000000 --- a/mParticle-Apple-SDK/Utils/MPDevice.h +++ /dev/null @@ -1,45 +0,0 @@ -#import -#import - -#if TARGET_OS_IOS == 1 - #import - #import -#endif - -extern NSString * _Nonnull const kMPDeviceInformationKey; -extern NSString * _Nonnull const kMPDeviceAdvertiserIdKey; - - -@interface MPDevice : NSObject - -#if TARGET_OS_IOS == 1 -@property (nonatomic, strong, readonly, nullable) CTCarrier *carrier; -@property (nonatomic, strong, readonly, nonnull) NSString *radioAccessTechnology; -#endif - -@property (nonatomic, strong, readonly, nullable) NSString *advertiserId; -@property (nonatomic, strong, readonly, nonnull) NSString *architecture; -@property (nonatomic, strong, readonly, nonnull) NSString *brand; -@property (nonatomic, strong, readonly, nullable) NSString *country; -@property (nonatomic, strong, readonly, nonnull) NSString *deviceIdentifier; -@property (nonatomic, strong, readonly, nullable) NSString *language; -@property (nonatomic, strong, readonly, nonnull) NSNumber *limitAdTracking; -@property (nonatomic, strong, readonly, nonnull) NSString *manufacturer __attribute__((const)); -@property (nonatomic, strong, readonly, nonnull) NSString *model; -@property (nonatomic, strong, readonly, nullable) NSString *name; -@property (nonatomic, strong, readonly, nonnull) NSString *platform __attribute__((const)); -@property (nonatomic, strong, readonly, nullable) NSString *product; -@property (nonatomic, strong, readonly, nullable) NSString *operatingSystem; -@property (nonatomic, strong, readonly, nonnull) NSString *timezoneOffset; -@property (nonatomic, strong, readonly, nullable) NSString *timezoneDescription; -@property (nonatomic, strong, readonly, nullable) NSString *vendorId; -@property (nonatomic, strong, readonly, nullable) NSString *buildId; -@property (nonatomic, readonly) CGSize screenSize; -@property (nonatomic, readonly) BOOL isDaylightSavingTime; -@property (nonatomic, readonly, getter = isTablet) BOOL tablet; - -+ (nonnull NSDictionary *)jailbrokenInfo; -- (nonnull NSDictionary *)dictionaryRepresentation; -- (nonnull NSDictionary *)dictionaryRepresentationWithMpid:(NSNumber *_Nullable)mpid; - -@end diff --git a/mParticle-Apple-SDK/Utils/MPDevice.m b/mParticle-Apple-SDK/Utils/MPDevice.m deleted file mode 100644 index c9dc5f881..000000000 --- a/mParticle-Apple-SDK/Utils/MPDevice.m +++ /dev/null @@ -1,594 +0,0 @@ -#import "MPDevice.h" -#import -#import -#import -#import "MPStateMachine.h" -#import -#import -#import -#import -#import -#import -#import "MPIConstants.h" -#import "mParticle.h" -#import "MPBackendController.h" -#import "MPILogger.h" -#import "MParticleSwift.h" - -#if TARGET_OS_IOS == 1 - #import "MPNotificationController.h" -#endif - -NSString *const kMPDeviceInformationKey = @"di"; -NSString *const kMPDeviceBrandKey = @"b"; -NSString *const kMPDeviceProductKey = @"p"; -NSString *const kMPDeviceNameKey = @"dn"; -NSString *const kMPDeviceAdvertiserIdKey = @"aid"; -NSString *const kMPDeviceAppVendorIdKey = @"vid"; -NSString *const kMPDeviceBuildIdKey = @"bid"; -NSString *const kMPDeviceManufacturerKey = @"dma"; -NSString *const kMPDevicePlatformKey = @"dp"; -NSString *const kMPDeviceOSKey = @"dosv"; -NSString *const kMPDeviceModelKey = @"dmdl"; -NSString *const kMPScreenHeightKey = @"dsh"; -NSString *const kMPScreenWidthKey = @"dsw"; -NSString *const kMPDeviceLocaleCountryKey = @"dlc"; -NSString *const kMPDeviceLocaleLanguageKey = @"dll"; -NSString *const kMPNetworkCountryKey = @"nc"; -NSString *const kMPNetworkCarrierKey = @"nca"; -NSString *const kMPMobileNetworkCodeKey = @"mnc"; -NSString *const kMPMobileCountryCodeKey = @"mcc"; -NSString *const kMPTimezoneOffsetKey = @"tz"; -NSString *const kMPTimezoneDescriptionKey = @"tzn"; -NSString *const kMPDeviceJailbrokenKey = @"jb"; -NSString *const kMPDeviceArchitectureKey = @"arc"; -NSString *const kMPDeviceRadioKey = @"dr"; -NSString *const kMPDeviceFloatingPointFormat = @"%0.0f"; -NSString *const kMPDeviceSignerIdentityString = @"signeridentity"; -NSString *const kMPDeviceIsTabletKey = @"it"; -NSString *const kMPDeviceIdentifierKey = @"deviceIdentifier"; -NSString *const kMPDeviceLimitAdTrackingKey = @"lat"; -NSString *const kMPDeviceIsDaylightSavingTime = @"idst"; -NSString *const kMPDeviceInvalidVendorId = @"00000000-0000-0000-0000-000000000000"; - -static NSDictionary *jailbrokenInfo = nil; - -int main(int argc, char *argv[]); - -@interface MPDevice() { - NSCalendar *calendar; - NSDictionary *deviceInfo; - BOOL isAdTrackingLimited; -#if TARGET_OS_IOS == 1 - CTTelephonyNetworkInfo *telephonyNetworkInfo; -#endif -} - -@end - -@interface MParticle () - -@property (nonatomic, strong, readonly) MPStateMachine_PRIVATE *stateMachine; -@property (nonatomic, strong, nonnull) MPBackendController_PRIVATE *backendController; - -@end - -@implementation MPDevice - -@synthesize advertiserId = _advertiserId; -@synthesize architecture = _architecture; -@synthesize deviceIdentifier = _deviceIdentifier; -@synthesize model = _model; -@synthesize vendorId = _vendorId; -@synthesize buildId = _buildId; -@synthesize screenSize = _screenSize; - -- (id)init { - self = [super init]; - if (!self) { - return nil; - } - - calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; - -#if TARGET_OS_IOS == 1 && !TARGET_OS_SIMULATOR - telephonyNetworkInfo = [[CTTelephonyNetworkInfo alloc] init]; -#endif - - return self; -} - -- (NSString *)description { - return [NSString stringWithFormat:@"%@", [self dictionaryRepresentation]]; -} - - -#pragma mark Accessors -- (NSString *)advertiserId { - NSDictionary *userIdentities = [[MParticle sharedInstance] identity].currentUser.identities; - return userIdentities[@(MPIdentityIOSAdvertiserId)]; -} - -- (NSString *)architecture { - if (_architecture) { - return _architecture; - } - - NSMutableString *cpu = [[NSMutableString alloc] init]; - size_t size; - cpu_type_t type; - cpu_subtype_t subtype; - size = sizeof(type); - sysctlbyname("hw.cputype", &type, &size, NULL, 0); - - size = sizeof(subtype); - sysctlbyname("hw.cpusubtype", &subtype, &size, NULL, 0); - - // values for cputype and cpusubtype defined in mach/machine.h - if (type == CPU_TYPE_X86) { - [cpu appendString:@"x86"]; - } else if (type == CPU_TYPE_ARM) { - [cpu appendString:@"arm"]; - - switch(subtype) { - case CPU_SUBTYPE_ARM_V7: - [cpu appendString:@"v7"]; - break; - - case CPU_SUBTYPE_ARM_V7S: - [cpu appendString:@"v7s"]; - break; - - default: - break; - } -#if !TARGET_IPHONE_SIMULATOR - } else if (type == CPU_TYPE_ARM64) { - [cpu appendString:@"arm64"]; -#endif - } else { - [cpu appendString:@"unknown"]; - } - - _architecture = [cpu copy]; - - return _architecture; -} - -- (NSString *)brand { - return [UIDevice currentDevice].model; -} - -#if TARGET_OS_IOS == 1 -- (CTCarrier *)carrier { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - return telephonyNetworkInfo.subscriberCellularProvider; -#pragma clang diagnostic pop -} - -- (NSString *)radioAccessTechnology { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - NSString *radioAccessTechnology = telephonyNetworkInfo.currentRadioAccessTechnology; -#pragma clang diagnostic pop - - if (radioAccessTechnology) { - NSRange range = [radioAccessTechnology rangeOfString:@"CTRadioAccessTechnology"]; - if (range.location != NSNotFound) { - radioAccessTechnology = [radioAccessTechnology substringFromIndex:NSMaxRange(range)]; - } else { - radioAccessTechnology = @"None"; - } - } else { - radioAccessTechnology = @"None"; - } - - return radioAccessTechnology; -} -#endif - -- (NSString *)country { - return [[NSLocale currentLocale] objectForKey:NSLocaleCountryCode]; -} - -- (NSString *)deviceIdentifier { - if (_deviceIdentifier) { - return _deviceIdentifier; - } - - MPUserDefaults *userDefaults = [MPUserDefaults standardUserDefaultsWithStateMachine:[MParticle sharedInstance].stateMachine backendController:[MParticle sharedInstance].backendController identity:[MParticle sharedInstance].identity]; - _deviceIdentifier = userDefaults[kMPDeviceIdentifierKey]; - if (!_deviceIdentifier) { - _deviceIdentifier = [[NSUUID UUID] UUIDString]; - userDefaults[kMPDeviceIdentifierKey] = _deviceIdentifier; - - dispatch_async(dispatch_get_main_queue(), ^{ - [userDefaults synchronize]; - }); - } - - return _deviceIdentifier; -} - -- (BOOL)isDaylightSavingTime { - BOOL isDaylightSavingTime = [[calendar timeZone] isDaylightSavingTime]; - return isDaylightSavingTime; -} - -- (BOOL)isTablet { - BOOL isTablet = [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad; - return isTablet; -} - -- (NSString *)language { - // Extra logic added to strip out the country code to stay consistent with earlier iOS releases - return [[[[NSLocale preferredLanguages] firstObject] componentsSeparatedByString:@"-"] firstObject]; -} - -- (NSNumber *)limitAdTracking { - return isAdTrackingLimited ? @YES : @NO; -} - -- (NSString *)manufacturer __attribute__((const)) { - return @"Apple"; -} - -- (NSString *)model { - if (_model) { - return _model; - } - - size_t size; - sysctlbyname("hw.machine", NULL, &size, NULL, 0); - char *name = malloc(size); - if (name) { - sysctlbyname("hw.machine", name, &size, NULL, 0); - _model = [NSString stringWithUTF8String:name]; - free(name); - } - - if (!_model) { - _model = @"Not available."; - } - - return _model; -} - -- (NSString *)name { - return [UIDevice currentDevice].name; -} - -- (NSString *)platform __attribute__((const)) { -#if TARGET_OS_IOS == 1 - return @"iOS"; -#elif TARGET_OS_TV == 1 - return @"tvOS"; -#else - return @"unknown"; -#endif -} - -- (NSString *)product { - return [UIDevice currentDevice].model; -} - -- (NSString *)operatingSystem { - return [UIDevice currentDevice].systemVersion; -} - -- (NSString *)timezoneOffset { - float timeZoneOffset = ([[NSTimeZone systemTimeZone] secondsFromGMT] / 3600.0); - return [NSString stringWithFormat:kMPDeviceFloatingPointFormat, timeZoneOffset]; -} - -- (NSString *)timezoneDescription { - return [[calendar timeZone] name]; -} - -- (NSString *)vendorId { - if (_vendorId) { - return _vendorId; - } - - _vendorId = [[[UIDevice currentDevice] identifierForVendor] UUIDString]; - MPUserDefaults *userDefaults = [MPUserDefaults standardUserDefaultsWithStateMachine:[MParticle sharedInstance].stateMachine backendController:[MParticle sharedInstance].backendController identity:[MParticle sharedInstance].identity]; - - if (_vendorId && ![_vendorId isEqualToString:kMPDeviceInvalidVendorId]) { - userDefaults[kMPDeviceAppVendorIdKey] = _vendorId; - [userDefaults synchronize]; - } - else { - _vendorId = userDefaults[kMPDeviceAppVendorIdKey]; - } - - return _vendorId; -} - -- (NSString *)buildId { - if (_buildId) { - return _buildId; - } - - size_t size; - sysctlbyname("kern.osversion", NULL, &size, NULL, 0); - char *buffer = malloc(size); - if (buffer) { - sysctlbyname("kern.osversion", buffer, &size, NULL, 0); - _buildId = [NSString stringWithUTF8String:buffer]; - free(buffer); - } - - return _buildId; -} - - -- (CGSize)screenSize { - if (!CGSizeEqualToSize(_screenSize, CGSizeZero)) { - return _screenSize; - } - - CGRect bounds = [[UIScreen mainScreen] bounds]; - CGFloat scale = [[UIScreen mainScreen] respondsToSelector:@selector(scale)] ? [[UIScreen mainScreen] scale] : 1.0; - _screenSize = CGSizeMake(bounds.size.width * scale, bounds.size.height * scale); - - return _screenSize; -} - -#pragma mark NSCopying -- (instancetype)copyWithZone:(NSZone *)zone { - MPDevice *copyObject = [[[self class] alloc] init]; - - if (copyObject) { - copyObject->_advertiserId = [_advertiserId copy]; - copyObject->_architecture = [_architecture copy]; - copyObject->_model = [_model copy]; - copyObject->_vendorId = [_vendorId copy]; - copyObject->_screenSize = _screenSize; - } - - return copyObject; -} - -#pragma mark Public class methods -+ (NSDictionary *)jailbrokenInfo { - if (jailbrokenInfo) { - return jailbrokenInfo; - } - - BOOL jailbroken = NO; - -#if !TARGET_OS_SIMULATOR - @try { - NSFileManager *fileManager = [NSFileManager defaultManager]; - NSString *filePath; - NSString *signerIdentityKey = nil; - NSDictionary *bundleInfoDictionary = [[NSBundle mainBundle] infoDictionary]; - NSEnumerator *infoEnumerator = [bundleInfoDictionary keyEnumerator]; - NSString *key; - - while ((key = [infoEnumerator nextObject])) { - if ([[key lowercaseString] isEqualToString:kMPDeviceSignerIdentityString]) { - signerIdentityKey = [key copy]; - break; - } - } - - jailbroken = signerIdentityKey != nil; - - if (!jailbroken) { - NSArray *filePaths = @[@"/usr/sbin/sshd", - @"/Library/MobileSubstrate/MobileSubstrate.dylib", - @"/bin/bash", - @"/usr/libexec/sftp-server", - @"/Applications/Cydia.app", - @"/Applications/blackra1n.app", - @"/Applications/FakeCarrier.app", - @"/Applications/Icy.app", - @"/Applications/IntelliScreen.app", - @"/Applications/MxTube.app", - @"/Applications/RockApp.app", - @"/Applications/SBSettings.app", - @"/Applications/WinterBoard.app", - @"/Library/MobileSubstrate/DynamicLibraries/LiveClock.plist", - @"/Library/MobileSubstrate/DynamicLibraries/Veency.plist", - @"/private/var/lib/apt", - @"/private/var/lib/cydia", - @"/private/var/mobile/Library/SBSettings/Themes", - @"/private/var/stash", - @"/private/var/tmp/cydia.log", - @"/System/Library/LaunchDaemons/com.ikey.bbot.plist", - @"/System/Library/LaunchDaemons/com.saurik.Cydia.Startup.plist"]; - - for (filePath in filePaths) { - jailbroken = [fileManager fileExistsAtPath:filePath]; - - if (jailbroken) { - break; - } - } - } - - if (!jailbroken) { - // Valid test only if running as root on a jailbroken device - NSData *jailbrokenTestData = [@"Jailbroken filesystem test." dataUsingEncoding:NSUTF8StringEncoding]; - filePath = @"/private/mpjailbrokentest.txt"; - jailbroken = [jailbrokenTestData writeToFile:filePath atomically:NO]; - - if (jailbroken) { - [fileManager removeItemAtPath:filePath error:nil]; - } - } - } @catch (NSException *e) { - MPILogError(@"Caught an exception trying to determine if jailbroken: %@", e); - - if (!jailbroken) { - NSString *symbols = [e.callStackSymbols description]; - if ([symbols containsString:@"xCon.dylib"]) { - jailbroken = YES; - } - } - } -#endif - - jailbrokenInfo = @{kMPDeviceCydiaJailbrokenKey:@(jailbroken)}; - - return jailbrokenInfo; -} - -#pragma mark Public instance methods -- (NSDictionary *)dictionaryRepresentation { - if (deviceInfo) { - return deviceInfo; - } - - NSMutableDictionary *deviceDictionary = [@{kMPDeviceBrandKey:self.model, - kMPDeviceNameKey:self.name, - kMPDeviceProductKey:self.model, - kMPDeviceOSKey:self.operatingSystem, - kMPDeviceModelKey:self.model, - kMPDeviceArchitectureKey:self.architecture, - kMPScreenWidthKey:[NSString stringWithFormat:kMPDeviceFloatingPointFormat, self.screenSize.width], - kMPScreenHeightKey:[NSString stringWithFormat:kMPDeviceFloatingPointFormat, self.screenSize.height], - kMPDevicePlatformKey:self.platform, - kMPDeviceManufacturerKey:self.manufacturer, - kMPTimezoneOffsetKey:self.timezoneOffset, - kMPTimezoneDescriptionKey:self.timezoneDescription, - kMPDeviceJailbrokenKey:[MPDevice jailbrokenInfo], - kMPDeviceIsTabletKey:@(self.tablet), - kMPDeviceIsDaylightSavingTime:@(self.isDaylightSavingTime)} - mutableCopy]; - - NSString *auxString; - auxString = self.language; - if (auxString) { - deviceDictionary[kMPDeviceLocaleLanguageKey] = auxString; - } - - auxString = self.country; - if (auxString) { - deviceDictionary[kMPDeviceLocaleCountryKey] = auxString; - } - - auxString = self.advertiserId; - if (auxString) { - deviceDictionary[kMPDeviceAdvertiserIdKey] = auxString; - } - - auxString = self.vendorId; - if (auxString) { - deviceDictionary[kMPDeviceAppVendorIdKey] = auxString; - } - - auxString = self.buildId; - if (auxString) { - deviceDictionary[kMPDeviceBuildIdKey] = auxString; - } - - NSNumber *limitAdTracking = self.limitAdTracking; - if (limitAdTracking != nil) { - deviceDictionary[kMPDeviceLimitAdTrackingKey] = limitAdTracking; - } - -#if TARGET_OS_IOS == 1 - deviceDictionary[kMPDeviceRadioKey] = self.radioAccessTechnology; - - CTCarrier *carrier = self.carrier; - if (carrier) { - auxString = carrier.carrierName; - if (auxString) { - deviceDictionary[kMPNetworkCarrierKey] = auxString; - } - - auxString = carrier.isoCountryCode; - if (auxString) { - deviceDictionary[kMPNetworkCountryKey] = auxString; - } - - auxString = carrier.mobileNetworkCode; - if (auxString) { - deviceDictionary[kMPMobileNetworkCodeKey] = auxString; - } - - auxString = carrier.mobileCountryCode; - if (auxString) { - deviceDictionary[kMPMobileCountryCodeKey] = auxString; - } - } - - NSData *pushNotificationToken; - if (![MPStateMachine_PRIVATE isAppExtension]) { - pushNotificationToken = [MPNotificationController_PRIVATE deviceToken]; - if (pushNotificationToken) { - NSString *tokenString = [MPUserDefaults stringFromDeviceToken:pushNotificationToken]; - if (tokenString) { - deviceDictionary[kMPDeviceTokenKey] = tokenString; - } - } - } -#endif - - if ([MParticle sharedInstance].stateMachine.deviceTokenType.length > 0) { - deviceDictionary[kMPDeviceTokenTypeKey] = [MParticle sharedInstance].stateMachine.deviceTokenType; - } - - NSNumber *authStatus = [MParticle sharedInstance].stateMachine.attAuthorizationStatus; - if (authStatus != nil) { - switch (authStatus.integerValue) { - case MPATTAuthorizationStatusNotDetermined: - deviceDictionary[kMPATT] = @"not_determined"; - [deviceDictionary removeObjectForKey:kMPDeviceAdvertiserIdKey]; - break; - case MPATTAuthorizationStatusRestricted: - deviceDictionary[kMPATT] = @"restricted"; - [deviceDictionary removeObjectForKey:kMPDeviceAdvertiserIdKey]; - break; - case MPATTAuthorizationStatusDenied: - deviceDictionary[kMPATT] = @"denied"; - [deviceDictionary removeObjectForKey:kMPDeviceAdvertiserIdKey]; - break; - case MPATTAuthorizationStatusAuthorized: - deviceDictionary[kMPATT] = @"authorized"; - break; - default: - break; - } - } - - NSNumber *authTimestamp = [MParticle sharedInstance].stateMachine.attAuthorizationTimestamp; - if (authTimestamp != nil) { - deviceDictionary[kMPATTTimestamp] = authTimestamp; - } - - BOOL cacheDeviceInfo = (auxString != nil) && (limitAdTracking != nil); - if (cacheDeviceInfo) { - deviceInfo = (NSDictionary *)deviceDictionary; - - return deviceInfo; - } else { - return (NSDictionary *)deviceDictionary; - } -} - -- (NSDictionary *)dictionaryRepresentationWithMpid:(NSNumber *)mpid { - NSMutableDictionary *deviceDictionary = [[self dictionaryRepresentation] mutableCopy]; - - if (mpid != nil) { - NSString *auxString; - NSDictionary *userIdentities = [[[MParticle sharedInstance] identity] getUser:mpid].identities; - auxString = userIdentities[@(MPIdentityIOSAdvertiserId)]; - NSNumber *currentStatus = [MParticle sharedInstance].stateMachine.attAuthorizationStatus; - if (auxString && (currentStatus == nil || currentStatus.integerValue == MPATTAuthorizationStatusAuthorized)) { - deviceDictionary[kMPDeviceAdvertiserIdKey] = auxString; - } - - auxString = userIdentities[@(MPIdentityIOSVendorId)]; - if (auxString) { - deviceDictionary[kMPDeviceAppVendorIdKey] = auxString; - } - } - - return deviceDictionary; -} - -@end diff --git a/mParticle-Apple-SDK/Utils/MPDevice.swift b/mParticle-Apple-SDK/Utils/MPDevice.swift new file mode 100644 index 000000000..75e55ef83 --- /dev/null +++ b/mParticle-Apple-SDK/Utils/MPDevice.swift @@ -0,0 +1,438 @@ +// +// MPDevice.swift +// mParticle-Apple-SDK +// +// Created by Brandon Stalnaker on 2/3/25. +// + +import Foundation +import QuartzCore +import MachO + +#if os(iOS) && !MPARTICLE_LOCATION_DISABLE +import CoreTelephony +#endif + +@objc public class MPDevice : NSObject, NSCopying { + private var stateMachine: MPStateMachine_PRIVATE + private var userDefaults: MPUserDefaults + private var identity: MPIdentityApi + + @objc required public init(stateMachine: MPStateMachine_PRIVATE, userDefaults: MPUserDefaults, identity: MPIdentityApi) { + self.stateMachine = stateMachine + self.userDefaults = userDefaults + self.identity = identity + super.init() + } + + @objc public func copy(with zone: NSZone? = nil) -> Any { + let copyObject = MPDevice(stateMachine: self.stateMachine, userDefaults: self.userDefaults, identity: self.identity) + + copyObject.advertiserId = self.advertiserId + copyObject.architecture = self.architecture + copyObject.model = self.model + copyObject.vendorId = self.vendorId + copyObject.screenSize = self.screenSize + + return copyObject + } + + private var _advertiserId: String? + @objc public private(set) var advertiserId: String? { + set { + _advertiserId = newValue + } + get { + if let adID = _advertiserId { + return adID + } else { + if let userIdentities = identity.currentUser?.identities as? [NSNumber: String] { + return userIdentities[NSNumber(value: MPIdentity.iosAdvertiserId.rawValue)] + } else { + return nil + } + } + } + } + + private var _architecture: String? + @objc public private(set) var architecture: String { + set { + _architecture = newValue + } + get { + if let arch = _architecture { + return arch + } else { + guard let archRaw = NXGetLocalArchInfo().pointee.name else { + return "unknown" + } + return String(cString: archRaw) + } + } + } + + @objc public var brand: String { + get { + return UIDevice.current.model + } + } + +#if os(iOS) && !MPARTICLE_LOCATION_DISABLE + @objc public var carrier: String? { + get { + // Deprecated and no longer provided by Apple https://developer.apple.com/documentation/coretelephony/cttelephonynetworkinfo/subscribercellularprovider + return nil + } + } + + @objc public var radioAccessTechnology: String { + get { + if let radioAccessTechnology = CTTelephonyNetworkInfo().currentRadioAccessTechnology { + if let range = radioAccessTechnology.range(of: "CTRadioAccessTechnology") { + if !range.isEmpty { + return String(radioAccessTechnology[...range.upperBound]) + } + } + } + return "None" + } + } +#endif + + @objc public var country: String? { + get { + return Locale.current.regionCode + } + } + + private var _deviceIdentifier: String? + @objc public var deviceIdentifier: String { + get { + if _deviceIdentifier == nil { + if let deviceID = userDefaults[Device.kMPDeviceIdentifierKey] as? String { + _deviceIdentifier = deviceID + } else { + _deviceIdentifier = UUID().uuidString + userDefaults[Device.kMPDeviceIdentifierKey] = _deviceIdentifier + } + } + return _deviceIdentifier ?? "" + } + } + + @objc public var language: String? { + get { + // Extra logic added to strip out the country code to stay consistent with earlier iOS releases + guard let subString = Locale.preferredLanguages[0].split(separator: "-").first else { + return nil + } + + return String(subString) + } + } + + @objc public var manufacturer: String { + get { + return "Apple" + } + } + + private var _model: String? + @objc public private(set) var model: String { + set { + _model = newValue + } + get { + if _model == nil { + var size = 0 + sysctlbyname("hw.machine", nil, &size, nil, 0) + var model = [CChar](repeating: 0, count: size) + sysctlbyname("hw.machine", &model, &size, nil, 0) + _model = String(cString: model) + } + + if let model = _model { + return model + } else { + return "Not available." + } + } + } + + @objc open var name: String { + get { + return UIDevice.current.name + } + } + + @objc open var platform: String { + get { + switch UIDevice.current.userInterfaceIdiom { + case .phone, .pad: + return "iOS" + case .tv: + return "tvOS" + default: + return "unknown" + + } + } + } + + @objc public var product: String? { + get { + return UIDevice.current.model + } + } + + @objc public var operatingSystem: String { + get { + return UIDevice.current.systemVersion + } + } + + @objc public var timezoneOffset: String { + get { + let timeZoneOffset = Calendar.current.timeZone.secondsFromGMT(for: Date()) / 3600 + return String(format: "%.1f", timeZoneOffset) + } + } + + @objc public var timezoneDescription: String { + get { + return Calendar.current.timeZone.identifier + } + } + + private var _vendorId: String? + @objc public private(set) var vendorId: String? { + set { + _vendorId = newValue + } + get { + if _vendorId == nil { + if let vendor = userDefaults[Device.kMPDeviceAppVendorIdKey] as? String, vendor != Device.kMPDeviceInvalidVendorId { + _vendorId = vendor + } else { + _vendorId = UUID().uuidString + } + } + return _vendorId + } + } + + @objc public var buildId: String? { + get { + var size = 0 + sysctlbyname("kern.osversion", nil, &size, nil, 0) + var build = [CChar](repeating: 0, count: size) + sysctlbyname("kern.osversion", &build, &size, nil, 0) + return String(cString: build) + } + } + + private var _screenSize: CGSize? + @objc public private(set) var screenSize: CGSize { + set { + _screenSize = newValue + } + get { + if let screenSize = _screenSize, !CGSizeEqualToSize(screenSize, CGSizeZero) { + return screenSize + } else { + let bounds = UIScreen.main.bounds + let scale: CGFloat = UIScreen.main.scale + let screenSize = CGSize(width: bounds.size.width * scale, height: bounds.height * scale) + _screenSize = screenSize + return screenSize + } + } + } + + @objc public var isDaylightSavingTime: Bool { + get { + let isDaylightSavingTime = TimeZone.current.isDaylightSavingTime() + return isDaylightSavingTime + } + } + + @objc public var isTablet: Bool { + get { + let isTablet = UI_USER_INTERFACE_IDIOM() == .pad + return isTablet + } + } + + @objc public class func jailbrokenInfo() -> [AnyHashable : Any] { + var jailbroken = false + +#if TARGET_IPHONE_SIMULATOR + // Simulator +#else + let fileManager = FileManager.default + var signerIdentityKey: String? + let bundleInfoDictionary = Bundle.main.infoDictionary + var key: String? + + if var infoEnumerator = bundleInfoDictionary?.keys.makeIterator() { + while (key != nil) { + key = infoEnumerator.next() + if let signerId = key?.copy() as? String, (signerId.lowercased() == Device.kMPDeviceSignerIdentityString) { + signerIdentityKey = signerId + break + } + } + } + + jailbroken = signerIdentityKey != nil + + if (!jailbroken) { + let filePaths = ["/usr/sbin/sshd", + "/Library/MobileSubstrate/MobileSubstrate.dylib", + "/bin/bash", + "/usr/libexec/sftp-server", + "/Applications/Cydia.app", + "/Applications/blackra1n.app", + "/Applications/FakeCarrier.app", + "/Applications/Icy.app", + "/Applications/IntelliScreen.app", + "/Applications/MxTube.app", + "/Applications/RockApp.app", + "/Applications/SBSettings.app", + "/Applications/WinterBoard.app", + "/Library/MobileSubstrate/DynamicLibraries/LiveClock.plist", + "/Library/MobileSubstrate/DynamicLibraries/Veency.plist", + "/private/var/lib/apt", + "/private/var/lib/cydia", + "/private/var/mobile/Library/SBSettings/Themes", + "/private/var/stash", + "/private/var/tmp/cydia.log", + "/System/Library/LaunchDaemons/com.ikey.bbot.plist", + "/System/Library/LaunchDaemons/com.saurik.Cydia.Startup.plist"] + + for filePath in filePaths { + jailbroken = fileManager.fileExists(atPath: filePath) + + if jailbroken { + break + } + } + + if !jailbroken { + // Valid test only if running as root on a jailbroken device + let jailbrokenTestData = "Jailbroken filesystem test.".data(using: .utf8) + let filePath = "/private/mpjailbrokentest.txt" + do { + try jailbrokenTestData?.write(to: URL(fileURLWithPath: filePath), options: []) + } catch { + MPLog.warning("Device is not jailbroken, failed to write test file: \(error)") + } + jailbroken = fileManager.fileExists(atPath: filePath) + + if jailbroken { + do { + try FileManager.default.removeItem(atPath: filePath) + } catch { + MPLog.error("Device is jailbroken and test file still exists, failed to remove test file: \(error)") + } + } + } + } +#endif + return [Miscellaneous.kMPDeviceCydiaJailbrokenKey:jailbroken ? 1 : 0] + } + + @objc public func dictionaryRepresentation() -> [AnyHashable : Any] { + var deviceDictionary: [AnyHashable : Any] = [Device.kMPDeviceBrandKey:self.model, + Device.kMPDeviceNameKey:self.name, + Device.kMPDeviceProductKey:self.model, + Device.kMPDeviceOSKey:self.operatingSystem, + Device.kMPDeviceModelKey:self.model, + Device.kMPDeviceArchitectureKey:self.architecture, + Device.kMPScreenWidthKey:String(format: Device.kMPDeviceFloatingPointFormat, self.screenSize.width), + Device.kMPScreenHeightKey:String(format: Device.kMPDeviceFloatingPointFormat, self.screenSize.height), + Device.kMPDevicePlatformKey:self.platform, + Device.kMPDeviceManufacturerKey:self.manufacturer, + Device.kMPTimezoneOffsetKey:self.timezoneOffset, + Device.kMPTimezoneDescriptionKey:self.timezoneDescription, + Device.kMPDeviceJailbrokenKey:MPDevice.jailbrokenInfo(), + Device.kMPDeviceIsTabletKey:self.isTablet ? 1 : 0, + Device.kMPDeviceIsDaylightSavingTime:self.isDaylightSavingTime ? 1 : 0] + + if let language = self.language { + deviceDictionary[Device.kMPDeviceLocaleLanguageKey] = language + } + + if let country = self.country { + deviceDictionary[Device.kMPDeviceLocaleCountryKey] = country + } + + if let advertiserId = self.advertiserId { + deviceDictionary[Device.kMPDeviceAdvertiserIdKey] = advertiserId + } + + if let vendorId = self.vendorId { + deviceDictionary[Device.kMPDeviceAppVendorIdKey] = vendorId + } + + if let buildId = self.buildId { + deviceDictionary[Device.kMPDeviceBuildIdKey] = buildId + } + +#if os(iOS) && !MPARTICLE_LOCATION_DISABLE + deviceDictionary[Device.kMPDeviceRadioKey] = self.radioAccessTechnology + + if let pushNotificationToken = MPNotificationController_PRIVATE.deviceToken() { + if let tokenString = MPUserDefaults.stringFromDeviceToken(pushNotificationToken) { + deviceDictionary[PushNotifications.kMPDeviceTokenKey] = tokenString + } + } +#endif + + if let noDeviceToken = stateMachine.deviceTokenType?.isEmpty, !noDeviceToken { + deviceDictionary[Miscellaneous.kMPDeviceTokenTypeKey] = stateMachine.deviceTokenType + } + + if let authStatus = stateMachine.attAuthorizationStatus { + switch authStatus.intValue { + case MPATTAuthorizationStatusSwift.notDetermined.rawValue: + deviceDictionary[Miscellaneous.kMPATT] = "not_determined" + case MPATTAuthorizationStatusSwift.restricted.rawValue: + deviceDictionary[Miscellaneous.kMPATT] = "restricted" + case MPATTAuthorizationStatusSwift.denied.rawValue: + deviceDictionary[Miscellaneous.kMPATT] = "denied" + case MPATTAuthorizationStatusSwift.authorized.rawValue: + deviceDictionary[Miscellaneous.kMPATT] = "authorized" + default: + break + } + } + + if let authTimestamp = stateMachine.attAuthorizationTimestamp { + deviceDictionary[Miscellaneous.kMPATTTimestamp] = authTimestamp + } + + return deviceDictionary + } + + @objc public func dictionaryRepresentation(withMpid mpid: NSNumber?) -> [AnyHashable : Any] { + var deviceDictionary: [AnyHashable : Any] = self.dictionaryRepresentation() + + if let mpid = mpid { + if let userIdentities = self.identity.getUser(mpid)?.identities { + if let advertiserId = userIdentities[MPIdentity.iosAdvertiserId.rawValue as NSNumber], + let currentStatus = stateMachine.attAuthorizationStatus, + currentStatus.intValue == MPATTAuthorizationStatusSwift.authorized.rawValue { + deviceDictionary[Device.kMPDeviceAdvertiserIdKey] = advertiserId + } + + if let vendorId = userIdentities[MPIdentity.iosVendorId.rawValue as NSNumber] { + deviceDictionary[Device.kMPDeviceAppVendorIdKey] = vendorId + } + } + } + + return deviceDictionary + } +} diff --git a/mParticle-Apple-SDK/Utils/MPUploadBuilder.m b/mParticle-Apple-SDK/Utils/MPUploadBuilder.m index 8eaf14638..5faf46747 100644 --- a/mParticle-Apple-SDK/Utils/MPUploadBuilder.m +++ b/mParticle-Apple-SDK/Utils/MPUploadBuilder.m @@ -8,7 +8,6 @@ #import "MPCustomModule.h" #import "MPConsumerInfo.h" #import "MPApplication.h" -#import "MPDevice.h" #import "MPForwardRecord.h" #import "MPIntegrationAttributes.h" #import "MPConsentState.h" @@ -160,7 +159,7 @@ - (void)build:(void (^)(MPUpload *upload))completionHandler { } else { // If the info wasn't saved in the session, use the old behavior and grab it now // NOTE: This should only ever happen the first time after upgrading to the new schema if there are old sessions left - MPDevice *device = [[MPDevice alloc] init]; + MPDevice *device = [[MPDevice alloc] initWithStateMachine:[MParticle sharedInstance].stateMachine userDefaults:[MPUserDefaults standardUserDefaultsWithStateMachine:[MParticle sharedInstance].stateMachine backendController:[MParticle sharedInstance].backendController identity:[MParticle sharedInstance].identity] identity:[MParticle sharedInstance].identity]; NSNumber *mpid = _uploadDictionary[kMPRemoteConfigMPIDKey]; _uploadDictionary[kMPDeviceInformationKey] = [device dictionaryRepresentationWithMpid:mpid]; } diff --git a/mParticle-Apple-SDK/mParticle.m b/mParticle-Apple-SDK/mParticle.m index 990f2e360..5d1608c02 100644 --- a/mParticle-Apple-SDK/mParticle.m +++ b/mParticle-Apple-SDK/mParticle.m @@ -1,7 +1,6 @@ #import "mParticle.h" #import "MPAppNotificationHandler.h" #import "MPConsumerInfo.h" -#import "MPDevice.h" #import "MPForwardQueueParameters.h" #import "MPForwardRecord.h" #import "MPIConstants.h"