Merge pull request #272 from Microsoft/feature/init-services-by-priority
Feature/init services by priority
This commit is contained in:
Коммит
6b907a92d5
|
@ -12,8 +12,6 @@
|
|||
static NSString *const kMSInstallIdKey = @"MSInstallId";
|
||||
static NSString *const kMSMobileCenterIsEnabledKey = @"MSMobileCenterIsEnabled";
|
||||
|
||||
@class MSService;
|
||||
|
||||
@interface MSMobileCenter ()
|
||||
|
||||
@property(nonatomic) id<MSLogManager> logManager;
|
||||
|
@ -57,4 +55,12 @@ static NSString *const kMSMobileCenterIsEnabledKey = @"MSMobileCenterIsEnabled";
|
|||
*/
|
||||
+ (NSString *)logTag;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
* Sort the array of services in descending order based on their priority.
|
||||
*
|
||||
* @return The array of services in descending order.
|
||||
*/
|
||||
- (NSArray *)sortServices:(NSArray<Class> *)services;
|
||||
|
||||
@end
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* Protocol declaring services common logic.
|
||||
* Protocol declaring public common logic for services.
|
||||
*/
|
||||
@protocol MSServiceCommon <NSObject>
|
||||
|
||||
|
@ -52,6 +52,11 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
*/
|
||||
@property(nonatomic, readonly) MSPriority priority;
|
||||
|
||||
/**
|
||||
* The initialization priority for this service.
|
||||
*/
|
||||
@property(nonatomic, readonly) MSInitializationPriority initializationPriority;
|
||||
|
||||
/**
|
||||
* Get the unique instance.
|
||||
*
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
|
||||
/**
|
||||
* Protocol declaring all the logic of a service. This is what concrete services needs to conform to.
|
||||
* The difference is that MSServiceCommon is public, while MSServiceInternal is private.
|
||||
* Some properties are present in both, which is counter-intuitive but the way we implemented this
|
||||
* to achieve abstraction and not have empty implementations in MSServiceAbstract.
|
||||
*/
|
||||
@protocol MSServiceInternal <MSService, MSServiceCommon>
|
||||
|
||||
|
@ -19,10 +22,15 @@
|
|||
@property(nonatomic, copy, readonly) NSString *storageKey;
|
||||
|
||||
/**
|
||||
* The channel priority for this service.
|
||||
* The channel priority for this service. Defined here as well as in MSServiceCommon to achieve abstraction.
|
||||
*/
|
||||
@property(nonatomic, readonly) MSPriority priority;
|
||||
|
||||
/**
|
||||
* The initialization priority for this service. Defined here as well as in MSServiceCommon to achieve abstraction.
|
||||
*/
|
||||
@property(nonatomic, readonly) MSInitializationPriority initializationPriority;
|
||||
|
||||
/**
|
||||
* The app secret for the SDK.
|
||||
*/
|
||||
|
@ -31,7 +39,7 @@
|
|||
/**
|
||||
* Get the unique instance.
|
||||
*
|
||||
* @return unique instance.
|
||||
* @return The unique instance.
|
||||
*/
|
||||
+ (instancetype)sharedInstance;
|
||||
|
||||
|
|
|
@ -17,10 +17,22 @@ static NSString *const kMSContentType = @"application/json";
|
|||
static NSString *const kMSAPIVersion = @"1.0.0-preview20160914";
|
||||
static NSString *const kMSAPIVersionKey = @"api_version";
|
||||
|
||||
// Channel priorities, check the kMSPriorityCount if you add a new value.
|
||||
typedef NS_ENUM(NSInteger, MSPriority) { MSPriorityDefault, MSPriorityBackground, MSPriorityHigh };
|
||||
/** Channel priorities, check the kMSPriorityCount if you add a new value.
|
||||
* The order matters here! Values NEED to range from low priority to high priority.
|
||||
*/
|
||||
typedef NS_ENUM(NSInteger, MSPriority) { MSPriorityBackground, MSPriorityDefault, MSPriorityHigh };
|
||||
static short const kMSPriorityCount = MSPriorityHigh + 1;
|
||||
|
||||
/**
|
||||
* The priority by which the modules are initialized.
|
||||
* MSPriorityMax is reserved for only 1 module and this needs to be Crashes. Crashes needs to be initialized first to
|
||||
* catch crashes in our other SDK Modules (which will hopefully never happen) and to avoid losing any log at crash time.
|
||||
*/
|
||||
typedef NS_ENUM(NSInteger, MSInitializationPriority) { MSInitializationPriorityDefault = 500, MSInitializationPriorityMax = 999 };
|
||||
|
||||
/**
|
||||
* Enum with the different HTTP status codes.
|
||||
*/
|
||||
typedef NS_ENUM(NSInteger, MSHTTPCodesNo) {
|
||||
// Informational
|
||||
MSHTTPCodesNo1XXInformationalUnknown = 1,
|
||||
|
|
|
@ -176,12 +176,35 @@ static NSString *const kMSDefaultBaseUrl = @"https://in.mobile.azure.com";
|
|||
- (void)start:(NSString *)appSecret withServices:(NSArray<Class> *)services {
|
||||
BOOL configured = [self configure:appSecret];
|
||||
if (configured) {
|
||||
for (Class service in services) {
|
||||
|
||||
NSArray *sortedServices = [self sortServices:services];
|
||||
|
||||
for (Class service in sortedServices) {
|
||||
[self startService:service];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray *)sortServices:(NSArray<Class> *)services {
|
||||
// Sort services in descending order to make sure the service with the highest priority gets initialized first.
|
||||
// This is intended to make sure Crashes gets initialized first.
|
||||
if (services && services.count > 1) {
|
||||
return [services sortedArrayUsingComparator:^NSComparisonResult(Class clazzA, Class clazzB) {
|
||||
id <MSServiceInternal> serviceA = [clazzA sharedInstance];
|
||||
id <MSServiceInternal> serviceB = [clazzB sharedInstance];
|
||||
|
||||
if (serviceA.initializationPriority < serviceB.initializationPriority) {
|
||||
return NSOrderedDescending;
|
||||
}
|
||||
else {
|
||||
return NSOrderedAscending;
|
||||
}
|
||||
}];
|
||||
} else {
|
||||
return services;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)startService:(Class)clazz {
|
||||
id<MSServiceInternal> service = [clazz sharedInstance];
|
||||
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
#import "MSMobileCenter.h"
|
||||
#import "MSMobileCenterInternal.h"
|
||||
#import "MSMobileCenterPrivate.h"
|
||||
#import "OCMock.h"
|
||||
#import <OCHamcrestIOS/OCHamcrestIOS.h>
|
||||
#import <XCTest/XCTest.h>
|
||||
#import "MSServiceInternal.h"
|
||||
|
||||
static NSString *const kSMInstallIdStringExample = @"F18499DA-5C3D-4F05-B4E8-D8C9C06A6F09";
|
||||
|
||||
|
@ -139,4 +141,24 @@ static NSString *const kSMNullifiedInstallIdString = @"00000000-0000-0000-0000-0
|
|||
[MSMobileCenter configureWithAppSecret:@"App-Secret"];
|
||||
XCTAssertTrue([MSMobileCenter isConfigured]);
|
||||
}
|
||||
|
||||
- (void)testSortingServicesWorks {
|
||||
|
||||
// If
|
||||
id<MSServiceCommon> mockServiceMaxPrio = OCMProtocolMock(@protocol(MSServiceCommon));
|
||||
OCMStub([mockServiceMaxPrio sharedInstance]).andReturn(mockServiceMaxPrio);
|
||||
OCMStub([mockServiceMaxPrio initializationPriority]).andReturn(MSInitializationPriorityMax);
|
||||
|
||||
id<MSServiceCommon> mockServiceDefaultPrio = OCMProtocolMock(@protocol(MSServiceCommon));
|
||||
OCMStub([mockServiceDefaultPrio sharedInstance]).andReturn(mockServiceDefaultPrio);
|
||||
OCMStub([mockServiceDefaultPrio initializationPriority]).andReturn(MSInitializationPriorityDefault);
|
||||
|
||||
// When
|
||||
NSArray<MSServiceAbstract *> *sorted = [self.sut sortServices:@[mockServiceDefaultPrio, mockServiceMaxPrio]];
|
||||
|
||||
// Then
|
||||
XCTAssertTrue([sorted[0] initializationPriority] == MSInitializationPriorityMax);
|
||||
XCTAssertTrue([sorted[1] initializationPriority] == MSInitializationPriorityDefault);
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -37,6 +37,10 @@
|
|||
return MSPriorityDefault;
|
||||
}
|
||||
|
||||
- (MSInitializationPriority)initializationPriority {
|
||||
return MSInitializationPriorityDefault;
|
||||
}
|
||||
|
||||
+ (NSString *)logTag {
|
||||
return @"MSServiceAbstractTest";
|
||||
}
|
||||
|
@ -319,4 +323,8 @@
|
|||
OCMVerify([logManagerMock setEnabled:YES andDeleteDataOnDisabled:YES forPriority:self.abstractService.priority]);
|
||||
}
|
||||
|
||||
- (void)testInitializationPriorityCorrect {
|
||||
XCTAssertTrue([self.abstractService initializationPriority] == MSInitializationPriorityDefault);
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -71,6 +71,10 @@ static dispatch_once_t onceToken;
|
|||
return MSPriorityDefault;
|
||||
}
|
||||
|
||||
- (MSInitializationPriority)initializationPriority {
|
||||
return MSInitializationPriorityDefault;
|
||||
}
|
||||
|
||||
#pragma mark - MSServiceAbstract
|
||||
|
||||
- (void)applyEnabledState:(BOOL)isEnabled {
|
||||
|
|
|
@ -268,4 +268,8 @@ static NSString *const kMSTestAppSecret = @"TestAppSecret";
|
|||
self.didFailSendingEventLogWasCalled = true;
|
||||
}
|
||||
|
||||
- (void)testInitializationPriorityCorrect {
|
||||
XCTAssertTrue([[MSAnalytics sharedInstance] initializationPriority] == MSInitializationPriorityDefault);
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -272,6 +272,10 @@ static void uncaught_cxx_exception_handler(const MSCrashesUncaughtCXXExceptionIn
|
|||
return MSPriorityHigh;
|
||||
}
|
||||
|
||||
- (MSInitializationPriority)initializationPriority {
|
||||
return MSInitializationPriorityMax;
|
||||
}
|
||||
|
||||
#pragma mark - MSLogManagerDelegate
|
||||
|
||||
/**
|
||||
|
@ -506,17 +510,18 @@ static void uncaught_cxx_exception_handler(const MSCrashesUncaughtCXXExceptionIn
|
|||
if ([[tmp pathExtension] isEqualToString:kMSLogBufferFileExtension]) {
|
||||
NSString *filePath = [self.logBufferDir stringByAppendingPathComponent:tmp];
|
||||
NSData *serializedLog = [NSData dataWithContentsOfFile:filePath];
|
||||
|
||||
id <MSLog> item = [NSKeyedUnarchiver unarchiveObjectWithData:serializedLog];
|
||||
if (item) {
|
||||
if ([((NSObject *) item) isKindOfClass:[MSAppleErrorLog class]]) {
|
||||
[self.logManager processLog:item withPriority:self.priority];
|
||||
} else {
|
||||
[self.logManager processLog:item withPriority:MSPriorityDefault];
|
||||
if(serializedLog && serializedLog.length && serializedLog.length > 0) {
|
||||
id <MSLog> item = [NSKeyedUnarchiver unarchiveObjectWithData:serializedLog];
|
||||
if (item) {
|
||||
if ([((NSObject *) item) isKindOfClass:[MSAppleErrorLog class]]) {
|
||||
[self.logManager processLog:item withPriority:self.priority];
|
||||
} else {
|
||||
[self.logManager processLog:item withPriority:MSPriorityDefault];
|
||||
}
|
||||
}
|
||||
// Create empty new file, overwrites the old one.
|
||||
[[NSFileManager defaultManager] createFileAtPath:filePath contents:[NSData data] attributes:nil];
|
||||
}
|
||||
// Create empty new file, overwrites the old one.
|
||||
[[NSFileManager defaultManager] createFileAtPath:filePath contents:[NSData data] attributes:nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -222,4 +222,8 @@ static NSString *const kMSTestAppSecret = @"TestAppSecret";
|
|||
XCTAssertTrue(self.sut.bufferIndex == 1);
|
||||
}
|
||||
|
||||
- (void)testInitializationPriorityCorrect {
|
||||
XCTAssertTrue([[MSCrashes sharedInstance] initializationPriority] == MSInitializationPriorityMax);
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
Загрузка…
Ссылка в новой задаче