From 7ae406759ce9a5c90a515c2c477881612b6e7ee0 Mon Sep 17 00:00:00 2001 From: Glavin Wiechert Date: Wed, 16 Jul 2014 11:56:42 -0300 Subject: [PATCH] Closes #9. Complete implementation / conversion to Promise style API. --- Common/SLModel.h | 11 +- Common/SLModel.m | 471 +++++++++--------- .../project.pbxproj | 2 - .../Streamlyne_iOS_SDKTests.m | 31 +- 4 files changed, 259 insertions(+), 256 deletions(-) diff --git a/Common/SLModel.h b/Common/SLModel.h index 66a1f45..559bc30 100644 --- a/Common/SLModel.h +++ b/Common/SLModel.h @@ -10,6 +10,7 @@ #import "CoreData+MagicalRecord.h" #import "SLObject.h" #import "SLValue.h" +#import /** `SLNode` is intended to be implemented and then subclassed. @@ -138,7 +139,7 @@ @param nid A valid `SLNid` for a node that will be retrieved from the database. @param callback A callback for when the asycronous request has returned with the node. */ -+ (void) readById:(SLNid)nid withCallback:(void (^)(SLModel *))callback; ++ (PMKPromise *) readById:(SLNid)nid; /** Returns the node with id corresponding to `SLNid`. @@ -146,7 +147,7 @@ @param filters `NSDictionary` representing the desired fields and relationships to be requested. @param callback A callback for when the asycronous request has returned with the node. */ -+ (void) readById:(SLNid)nid withFilters:(NSDictionary *)filters withCallback:(void (^)(SLModel *))callback; ++ (PMKPromise *) readById:(SLNid)nid withFilters:(NSDictionary *)filters; /** @@ -161,7 +162,7 @@ @deprecate Use `readAllWithAPIManager` instead. */ -+ (void) readAllWithCallback:(void (^)(NSArray *))callback DEPRECATED_ATTRIBUTE; ++ (PMKPromise *) readAll; /** Returns all nodes of the type subclassed by `SLNode`. @@ -172,7 +173,7 @@ @deprecate Use `readAllWithAPIManager` instead. */ -+ (void) readAllWithFilters:(NSDictionary *)filters withCallback:(void (^)(NSArray *))callback DEPRECATED_ATTRIBUTE; ++ (PMKPromise *) readAllWithFilters:(NSDictionary *)filters; /** Returns all nodes of the type subclassed by `SLNode`. @@ -182,7 +183,7 @@ @param filters `NSDictionary` representing the desired fields and relationships to be requested. @return void */ -+ (void) readAllWithAPIManager:(SLAPIManager *)manager withFilters:(NSDictionary *)filters withCallback:(void (^)(NSArray *))callback; ++ (PMKPromise *) readAllWithAPIManager:(SLAPIManager *)manager withFilters:(NSDictionary *)filters; /** diff --git a/Common/SLModel.m b/Common/SLModel.m index 89708cb..2090e37 100644 --- a/Common/SLModel.m +++ b/Common/SLModel.m @@ -53,10 +53,10 @@ - (instancetype) initInContext:(NSManagedObjectContext *)context self.data = tempData; /* - // Edit data mapping - NSMutableDictionary *tempDataMapping = [self.dataMapping mutableCopy]; - [tempDataMapping setObject:@{ @"class": @"NSNumber", @"key": @"nid" } forKey:@"nid"]; - self.dataMapping = tempDataMapping; + // Edit data mapping + NSMutableDictionary *tempDataMapping = [self.dataMapping mutableCopy]; + [tempDataMapping setObject:@{ @"class": @"NSNumber", @"key": @"nid" } forKey:@"nid"]; + self.dataMapping = tempDataMapping; */ } return self; @@ -72,13 +72,13 @@ + (instancetype) initWithId:(SLNid)nid inContext:(NSManagedObjectContext *)conte { __block SLModel *node; //[context performBlockAndWait:^(void){ - NSLog(@"initWithId, before find node"); - node = [[self class] MR_findFirstByAttribute:@"nid" withValue:nid inContext:context]; - NSLog(@"initWithId: %@, node: %@", nid, node); - if (node == nil) { - node = [[[self class] alloc] initInContext:context]; - node.nid = nid; - } + NSLog(@"initWithId, before find node"); + node = [[self class] MR_findFirstByAttribute:@"nid" withValue:nid inContext:context]; + NSLog(@"initWithId: %@, node: %@", nid, node); + if (node == nil) { + node = [[[self class] alloc] initInContext:context]; + node.nid = nid; + } //}]; return node; } @@ -137,7 +137,7 @@ - (void) loadDataFromDictionary:(NSDictionary *)theData NSLocale *enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; [iso8601Formatter setLocale:enUSPOSIXLocale]; [iso8601Formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZZZZZ"]; - + // Load Data from NSDictionary NSLog(@"%@", theData); NSString *key = nil; @@ -163,12 +163,12 @@ - (void) loadDataFromDictionary:(NSDictionary *)theData [self setValue:d forKey:mKey]; } /* - // NSLog(@"Update %@: %@", key, [theData objectForKey:key]); - [self update:mKey value:[theData objectForKey:key]]; - // Mark data as saved. - SLValue *val = [self.data objectForKey:key]; - [val setSaved]; // Mark as saved. - */ + // NSLog(@"Update %@: %@", key, [theData objectForKey:key]); + [self update:mKey value:[theData objectForKey:key]]; + // Mark data as saved. + SLValue *val = [self.data objectForKey:key]; + [val setSaved]; // Mark as saved. + */ } } @@ -199,7 +199,7 @@ + (NSString *) type userInfo:nil]; } -+ (void) readById:(SLNid)nid withCallback:(void (^)(SLModel *))callback ++ (PMKPromise *) readById:(SLNid)nid { NSDictionary *filters = @{ @"filter":@{ @@ -207,40 +207,46 @@ + (void) readById:(SLNid)nid withCallback:(void (^)(SLModel *))callback @"rels": [NSNumber numberWithBool: TRUE] } }; - [self readById:nid withFilters:filters withCallback:callback]; + return [self readById:nid withFilters:filters]; } -+ (void) readById:(SLNid)nid withFilters:(NSDictionary *)filters withCallback:(void (^)(SLModel *))callback ++ (PMKPromise *) readById:(SLNid)nid withFilters:(NSDictionary *)filters { - SLAPIManager *manager = [[self class] sharedAPIManager]; - - [MagicalRecord saveWithBlock:^(NSManagedObjectContext *context) { + return [PMKPromise new:^(PMKPromiseFulfiller fulfiller, PMKPromiseRejecter rejecter) { - SLRequestCallback completionBlock = ^(NSError *error, id operation, id responseObject) { - //NSLog(@"SLRequestCallback completionBlock!"); - //NSLog(@"<%@>: %@", [responseObject class], responseObject); + SLAPIManager *manager = [[self class] sharedAPIManager]; + + [MagicalRecord saveWithBlock:^(NSManagedObjectContext *context) { - // Process & Read Node - SLModel *node = [[self class] initWithId:(SLNid) responseObject[@"id"] inContext:context]; - node.syncState = @(SLSyncStateSynced); - [((SLModel *)node) loadDataFromDictionary: responseObject[@"data"]]; - [((SLModel *)node) loadRelsFromArray: responseObject[@"rels"] inContext:context]; + SLRequestCallback completionBlock = ^(NSError *error, id operation, id responseObject) { + //NSLog(@"SLRequestCallback completionBlock!"); + //NSLog(@"<%@>: %@", [responseObject class], responseObject); + + // Process & Read Node + SLModel *node = [[self class] initWithId:(SLNid) responseObject[@"id"] inContext:context]; + node.syncState = @(SLSyncStateSynced); + [((SLModel *)node) loadDataFromDictionary: responseObject[@"data"]]; + [((SLModel *)node) loadRelsFromArray: responseObject[@"rels"] inContext:context]; + + // Return + // callback(node); // Returning in completion block now. + [context MR_saveToPersistentStoreAndWait]; + }; + + NSString *thePath = [NSString stringWithFormat:@"%@/%@", [[self class] type],nid]; + [manager performRequestWithMethod:SLHTTPMethodGET withPath:thePath withParameters:filters] + .then(completionBlock); + } completion:^(BOOL success, NSError *error) { // Return - // callback(node); // Returning in completion block now. - [context MR_saveToPersistentStoreAndWait]; - }; + fulfiller( [[self class] MR_findFirstByAttribute:@"nid" withValue:nid] ); + }]; + - NSString *thePath = [NSString stringWithFormat:@"%@/%@", [[self class] type],nid]; - [manager performRequestWithMethod:SLHTTPMethodGET withPath:thePath withParameters:filters withCallback:completionBlock]; - - } completion:^(BOOL success, NSError *error) { - // Return - callback( [[self class] MR_findFirstByAttribute:@"nid" withValue:nid] ); }]; } -+ (void) readAllWithCallback:(void (^)(NSArray *))callback ++ (PMKPromise *) readAll { NSDictionary *filters = @{ @"filter":@{ @@ -248,65 +254,59 @@ + (void) readAllWithCallback:(void (^)(NSArray *))callback @"rels": [NSNumber numberWithBool: TRUE] } }; - [self readAllWithFilters:filters withCallback:callback]; + return [self readAllWithFilters:filters]; } -+ (void) readAllWithFilters:(NSDictionary *)filters withCallback:(void (^)(NSArray *))callback ++ (PMKPromise *) readAllWithFilters:(NSDictionary *)filters withCallback:(void (^)(NSArray *))callback { SLAPIManager *manager = [[self class] sharedAPIManager]; NSLog(@"Manager: %@", manager); - [self readAllWithAPIManager:manager withFilters:filters withCallback:callback]; + return [self readAllWithAPIManager:manager withFilters:filters]; } -+ (void) readAllWithAPIManager:(SLAPIManager *)manager withFilters:(NSDictionary *)filters withCallback:(void (^)(NSArray *))callback ++ (PMKPromise *) readAllWithAPIManager:(SLAPIManager *)manager withFilters:(NSDictionary *)filters { - - __block NSManagedObjectContext *context = [NSManagedObjectContext MR_defaultContext]; - - [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) { - __block BOOL waiting = TRUE; + return [PMKPromise new:^(PMKPromiseFulfiller fulfiller, PMKPromiseRejecter rejecter) { - SLRequestCallback completionBlock = ^(NSError *error, id operation, id responseObject) { - NSLog(@"SLRequestCallback completionBlock."); - NSLog(@"<%@>: %@", [responseObject class], responseObject); - NSMutableArray *nodes = [NSMutableArray array]; - NSArray *arr = ((NSDictionary *)responseObject)[@"nodes"]; - for (NSDictionary* curr in arr) - { - NSLog(@"curr: %@", curr); - SLModel *node = [[self class] initWithId:(SLNid) curr[@"id"] inContext:context]; - node.syncState = @(SLSyncStateSynced); - [((SLModel *)node) loadDataFromDictionary: curr[@"data"]]; - [((SLModel *)node) loadRelsFromArray: curr[@"rels"] inContext:context]; + __block NSManagedObjectContext *context = [NSManagedObjectContext MR_defaultContext]; + + [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) { + + SLRequestCallback completionBlock = ^(NSError *error, id operation, id responseObject) { + NSLog(@"SLRequestCallback completionBlock."); + NSLog(@"<%@>: %@", [responseObject class], responseObject); + NSMutableArray *nodes = [NSMutableArray array]; + NSArray *arr = ((NSDictionary *)responseObject)[@"nodes"]; + for (NSDictionary* curr in arr) + { + NSLog(@"curr: %@", curr); + SLModel *node = [[self class] initWithId:(SLNid) curr[@"id"] inContext:context]; + node.syncState = @(SLSyncStateSynced); + [((SLModel *)node) loadDataFromDictionary: curr[@"data"]]; + [((SLModel *)node) loadRelsFromArray: curr[@"rels"] inContext:context]; + + [nodes addObject: node]; + NSLog(@"Node: %@",node); + + } + // callback(nodes); // returning in the completion block + [context MR_saveToPersistentStoreAndWait]; + [localContext save:nil]; - [nodes addObject: node]; - NSLog(@"Node: %@",node); + // + NSLog(@"Done!!!"); + NSLog(@"%@ %@", context, localContext); - } - // callback(nodes); // returning in the completion block - [context MR_saveToPersistentStoreAndWait]; - [localContext save:nil]; + // Return all nodes! + fulfiller( [[self class] MR_findAll] ); + + }; - // - waiting = FALSE; - NSLog(@"Done!!!"); + [manager performRequestWithMethod:SLHTTPMethodGET withPath:[[self class] type] withParameters:filters] + .then(completionBlock); - NSLog(@"%@ %@", context, localContext); - }; - - waiting = TRUE; - [manager performRequestWithMethod:SLHTTPMethodGET withPath:[[self class] type] withParameters:filters withCallback:completionBlock]; - - // Wait - NSDate *loopUntil = [NSDate dateWithTimeIntervalSinceNow:0.1]; - while (waiting && [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate:loopUntil]) { - loopUntil = [NSDate dateWithTimeIntervalSinceNow:0.1]; - } - - NSLog(@"Completed, pending: %d", waiting); + }]; - // Return all nodes! - callback( [[self class] MR_findAll] ); }]; } @@ -322,14 +322,14 @@ + (instancetype) createWithData:(NSDictionary *)theData withRels:(NSArray *)theR // Data [node loadDataFromDictionary:theData]; /* - NSString *key = nil; - for (key in theData) - { - NSLog(@"Update %@: %@", key, [theData objectForKey:key]); - [node update:key value:[theData objectForKey:key]]; - [node setValue:[theData objectForKey:key] forKey:key]; - } - */ + NSString *key = nil; + for (key in theData) + { + NSLog(@"Update %@: %@", key, [theData objectForKey:key]); + [node update:key value:[theData objectForKey:key]]; + [node setValue:[theData objectForKey:key] forKey:key]; + } + */ // FIXME: This is deprecated. Switch to Core Data // Rels SLRelationship *currRel; @@ -356,27 +356,20 @@ + (instancetype) create return [[self class] createWithData:nil withRels:nil]; } -+ (void)deleteWithId:(SLNid)nid ++ (PMKPromise *) deleteWithId:(SLNid)nid { - [self deleteWithId:nid withCallback:nil]; -} - -+ (void) deleteWithId:(SLNid)nid withCallback:(SLSuccessCallback)callback -{ - SLRequestCallback completionBlock = ^(NSError *error, id operation, id responseObject) { NSLog(@"SLRequestCallback completionBlock!"); NSLog(@"<%@>: %@", [responseObject class], responseObject); // TODO: Check if successful - callback(true); + fulfiller(true); }; NSString *thePath = [NSString stringWithFormat:@"%@/%@", [[self class] type],nid]; NSLog(@"theDeletePath: %@", thePath); - [[[self class] sharedAPIManager] performRequestWithMethod:SLHTTPMethodDELETE withPath:thePath withParameters:nil withCallback:completionBlock]; - + return [[[self class] sharedAPIManager] performRequestWithMethod:SLHTTPMethodDELETE withPath:thePath withParameters:nil]; } + (void) deleteWithNode:(SLModel *)node @@ -442,22 +435,22 @@ __block void (^ completionCallback)() = ^{ } /* -- (NSString *) description -{ - //return [NSString stringWithFormat:@"<%@>", [self class]]; - - return [NSString stringWithFormat:@"<%@ %p: %@>", [self class], self, - [NSDictionary dictionaryWithObjectsAndKeys: - NSNullIfNil([self nid]), @"id", - NSNullIfNil([self type]), @"type", - NSNullIfNil([self.data description]), @"data", - NSNullIfNil([self.rels description]), @"relationships", - nil - ] ]; - - //return [NSString stringWithFormat:@"<%@: { type: \"%@\", data: %@, relationships: %@ } >", [self class], [self type], [self.data description], [self.rels description]]; -} -*/ + - (NSString *) description + { + //return [NSString stringWithFormat:@"<%@>", [self class]]; + + return [NSString stringWithFormat:@"<%@ %p: %@>", [self class], self, + [NSDictionary dictionaryWithObjectsAndKeys: + NSNullIfNil([self nid]), @"id", + NSNullIfNil([self type]), @"type", + NSNullIfNil([self.data description]), @"data", + NSNullIfNil([self.rels description]), @"relationships", + nil + ] ]; + + //return [NSString stringWithFormat:@"<%@: { type: \"%@\", data: %@, relationships: %@ } >", [self class], [self type], [self.data description], [self.rels description]]; + } + */ - (NSString *) type { @@ -520,134 +513,138 @@ - (void) saveWithCallback:(SLSuccessCallback)callback callback(false); } -- (void) pushWithAPIManager:(SLAPIManager *)manager withCallback:(SLSuccessCallback)callback +- (PMKPromise *) pushWithAPIManager:(SLAPIManager *)manager { - //NSLog(@"pushWithAPIManager:withCallback:"); - - NSLog(@"serializeData: %@", [self serializeData]); - - // Create serialized delta - NSMutableDictionary *notSavedData = [NSMutableDictionary dictionary]; - /* - NSString *key; - for (key in data) - { - SLValue *val = [self.data objectForKey:key]; - // Check if already saved - if (![val isSaved]) - { - // Value is not already saved - [notSavedData setObject:[val get] forKey:key]; - } - } - */ - notSavedData = [NSMutableDictionary dictionaryWithDictionary: [self serializeData]]; - - // - NSMutableArray *notSavedRels = [NSMutableArray array]; - SLRelationship* rel; - for (rel in self.rels) - { - // Check if already saved - if (![rel isSaved]) + return [PMKPromise new:^(PMKPromiseFulfiller fulfiller, PMKPromiseRejecter rejecter) { + + + //NSLog(@"pushWithAPIManager:withCallback:"); + + NSLog(@"serializeData: %@", [self serializeData]); + + // Create serialized delta + NSMutableDictionary *notSavedData = [NSMutableDictionary dictionary]; + /* + NSString *key; + for (key in data) + { + SLValue *val = [self.data objectForKey:key]; + // Check if already saved + if (![val isSaved]) + { + // Value is not already saved + [notSavedData setObject:[val get] forKey:key]; + } + } + */ + notSavedData = [NSMutableDictionary dictionaryWithDictionary: [self serializeData]]; + + // + NSMutableArray *notSavedRels = [NSMutableArray array]; + SLRelationship* rel; + for (rel in self.rels) { - SLRelationshipDirection dir = [rel directionWithNode:self]; - NSLog(@"%@", rel); - if (dir == SLRelationshipIncoming) { - SLModel *node = rel.startNode; - NSLog(@"%@", node); - if (node != nil && node.nid != nil) { - NSLog(@"%@, %@, %@, %@", node, node.nid, [rel.startNode type], rel.name); - [notSavedRels addObject:@{ - @"id":node.nid, - @"dir":@"in", - @"nodeType": [rel.startNode type], - @"relsType": rel.name - }]; - } else { - NSLog(@"Other node, %@, not yet pushed to server.", node); - } - } else if (dir == SLRelationshipOutgoing) { - SLModel *node = rel.endNode; - if (node != nil && node.nid != nil) { - [notSavedRels addObject:@{ - @"id":node.nid, - @"dir":@"out", - @"nodeType": [rel.endNode type], - @"relsType": rel.name - }]; + // Check if already saved + if (![rel isSaved]) + { + SLRelationshipDirection dir = [rel directionWithNode:self]; + NSLog(@"%@", rel); + if (dir == SLRelationshipIncoming) { + SLModel *node = rel.startNode; + NSLog(@"%@", node); + if (node != nil && node.nid != nil) { + NSLog(@"%@, %@, %@, %@", node, node.nid, [rel.startNode type], rel.name); + [notSavedRels addObject:@{ + @"id":node.nid, + @"dir":@"in", + @"nodeType": [rel.startNode type], + @"relsType": rel.name + }]; + } else { + NSLog(@"Other node, %@, not yet pushed to server.", node); + } + } else if (dir == SLRelationshipOutgoing) { + SLModel *node = rel.endNode; + if (node != nil && node.nid != nil) { + [notSavedRels addObject:@{ + @"id":node.nid, + @"dir":@"out", + @"nodeType": [rel.endNode type], + @"relsType": rel.name + }]; + } else { + NSLog(@"Other node, %@, not yet pushed to server.", node); + } } else { - NSLog(@"Other node, %@, not yet pushed to server.", node); + // SLRelationshipNotFound + NSLog(@"SLRelationshipNotFound"); + //[notSavedRels addObject:rel]; + @throw SLExceptionImplementationNotFound; } - } else { - // SLRelationshipNotFound - NSLog(@"SLRelationshipNotFound"); - //[notSavedRels addObject:rel]; - @throw SLExceptionImplementationNotFound; } + } - } - - NSLog(@"delta: %@, %@", notSavedData, notSavedRels); - NSDictionary *delta = @{@"data": notSavedData, @"rels": notSavedRels}; - NSLog(@"Save data: %@", delta); - - // POST the CREATE/UPDATE - SLRequestCallback completionBlock = ^(NSError *error, id operation, id responseObject) { - NSLog(@"SLRequestCallback completionBlock!"); - NSLog(@"<%@>: %@", [responseObject class], responseObject); + NSLog(@"delta: %@, %@", notSavedData, notSavedRels); + NSDictionary *delta = @{@"data": notSavedData, @"rels": notSavedRels}; + NSLog(@"Save data: %@", delta); - // TODO: Check if successful, then mark the successful data and relationship fields as `saved` - if (error == nil) - { - NSDictionary *responseData = (NSDictionary *)responseObject; - - // Update the Node Id. - [self setNid:responseData[@"id"]]; - [self setSyncState:@(SLSyncStateSynced)]; - - // Mark all `SLValue`s as saved. - NSString *key; - for (key in self.data) - { - SLValue *val = [self.data objectForKey:key]; - [val setSaved]; // Mark as saved. - } + // POST the CREATE/UPDATE + SLRequestCallback completionBlock = ^(NSError *error, id operation, id responseObject) { + NSLog(@"SLRequestCallback completionBlock!"); + NSLog(@"<%@>: %@", [responseObject class], responseObject); - // Mark all `SLRelationship`s as saved. - SLRelationship* rel; - for (rel in self.rels) + // TODO: Check if successful, then mark the successful data and relationship fields as `saved` + if (error == nil) { - [rel setSaved]; + NSDictionary *responseData = (NSDictionary *)responseObject; + + // Update the Node Id. + [self setNid:responseData[@"id"]]; + [self setSyncState:@(SLSyncStateSynced)]; + + // Mark all `SLValue`s as saved. + NSString *key; + for (key in self.data) + { + SLValue *val = [self.data objectForKey:key]; + [val setSaved]; // Mark as saved. + } + + // Mark all `SLRelationship`s as saved. + SLRelationship* rel; + for (rel in self.rels) + { + [rel setSaved]; + } + // Mark Node as saved. + _saved = YES; + + // Return + fulfiller(nil); + + } else { + rejecter(nil); } - // Mark Node as saved. - _saved = YES; - - // Return - callback(true); - - } else { - callback(false); + }; + // + NSString *thePath; + if (self.nid == SLNidNodeNotCreated) + { + // New (CREATE) + NSLog(@"CREATE %@", self); + thePath = [NSString stringWithFormat:@"%@", [[self class] type]]; + } else + { + // Update (UPDATE) + NSLog(@"UPDATE %@", self); + thePath = [NSString stringWithFormat:@"%@/%@", [[self class] type],self.nid]; } - }; - // - NSString *thePath; - if (self.nid == SLNidNodeNotCreated) - { - // New (CREATE) - NSLog(@"CREATE %@", self); - thePath = [NSString stringWithFormat:@"%@", [[self class] type]]; - } else - { - // Update (UPDATE) - NSLog(@"UPDATE %@", self); - thePath = [NSString stringWithFormat:@"%@/%@", [[self class] type],self.nid]; - } - NSLog(@"Save Path: %@", thePath); - NSLog(@"Manager: %@", manager); - [manager performRequestWithMethod:SLHTTPMethodPOST withPath:thePath withParameters:delta withCallback:completionBlock]; - + NSLog(@"Save Path: %@", thePath); + NSLog(@"Manager: %@", manager); + [manager performRequestWithMethod:SLHTTPMethodPOST withPath:thePath withParameters:delta].then(completionBlock); + + }]; } diff --git a/Streamlyne Cocoa SDK.xcodeproj/project.pbxproj b/Streamlyne Cocoa SDK.xcodeproj/project.pbxproj index 1881d78..79d7a22 100644 --- a/Streamlyne Cocoa SDK.xcodeproj/project.pbxproj +++ b/Streamlyne Cocoa SDK.xcodeproj/project.pbxproj @@ -124,7 +124,6 @@ 77BE8F291877B8AF0098C907 /* Streamlyne.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 771F4B95186029D90093674F /* Streamlyne.xcdatamodeld */; }; 77ED5DB0183FE91500905A3D /* Streamlyne_iOS_SDKTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7720FC3618369CA20092D39B /* Streamlyne_iOS_SDKTests.m */; }; 92F7ADA5AAA84B5CB9EC0C92 /* libPods-Streamlyne-Mac-SDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BD262B1AFB1147419CB78D50 /* libPods-Streamlyne-Mac-SDK.a */; }; - 9FAB3B915AEF4B3C91CD4925 /* libPods-Streamlyne-iOS-SDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 43C9C0453FF246D08D7516AD /* libPods-Streamlyne-iOS-SDK.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -244,7 +243,6 @@ buildActionMask = 2147483647; files = ( 7720FC1B18369CA10092D39B /* Foundation.framework in Frameworks */, - 9FAB3B915AEF4B3C91CD4925 /* libPods-Streamlyne-iOS-SDK.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Streamlyne-iOS-SDKTests/Streamlyne_iOS_SDKTests.m b/Streamlyne-iOS-SDKTests/Streamlyne_iOS_SDKTests.m index 79933ff..9ebcdf1 100644 --- a/Streamlyne-iOS-SDKTests/Streamlyne_iOS_SDKTests.m +++ b/Streamlyne-iOS-SDKTests/Streamlyne_iOS_SDKTests.m @@ -16,14 +16,23 @@ @interface Streamlyne_iOS_SDKTests : XCTestCase @implementation Streamlyne_iOS_SDKTests -// Helper methods -- (void) waitUntilFinishedPending:(int*) pendingCallbacks { - NSDate *loopUntil = [NSDate dateWithTimeIntervalSinceNow:0.1]; - while ((*pendingCallbacks > 0) && [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate:loopUntil]) { - //NSLog(@"%d", pendingCallbacks); - loopUntil = [NSDate dateWithTimeIntervalSinceNow:0.1]; - } -} +// Macro - Set the flag for block completion +#define StartBlock() __block BOOL waitingForBlock = YES + +// Macro - Set the flag to stop the loop +#define EndBlock() waitingForBlock = NO + +// Macro - Wait and loop until flag is set +#define WaitUntilBlockCompletes() WaitWhile(waitingForBlock) + +// Macro - Wait for condition to be NO/false in blocks and asynchronous calls +// Each test should have its own instance of a BOOL condition because of non-thread safe operations +#define WaitWhile(condition) \ +do { \ +while(condition) { \ +[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; \ +} \ +} while(0) // @@ -43,10 +52,6 @@ - (void)setUp withPassword:@"testing" withOrganization:@"test"]; -// [manager setEmail:@"testing@streamlyne.co"]; -// [manager setPassword:@"testing"]; -// [manager setOrganization:@"test"]; - [MagicalRecord setDefaultModelFromClass:[self class]]; [MagicalRecord setupCoreDataStackWithInMemoryStore]; @@ -63,6 +68,8 @@ - (void)tearDown [super tearDown]; } + + - (void) testAuthentication { __block int pendingCallbacks = 0;