diff --git a/.github/workflows/release-package.yml b/.github/workflows/release-package.yml index 8685083..2868423 100644 --- a/.github/workflows/release-package.yml +++ b/.github/workflows/release-package.yml @@ -29,4 +29,4 @@ jobs: - name: CocoaPods trunk push run: pod trunk push --allow-warnings env: - COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }} \ No newline at end of file + COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }} diff --git a/.gitignore b/.gitignore index 66ea262..25e6328 100755 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ # Xcode # # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore - +.vscode/ ## Build generated Build/ diff --git a/Contentstack/Stack.h b/Contentstack/Stack.h index 48ff064..7c5dfe0 100644 --- a/Contentstack/Stack.h +++ b/Contentstack/Stack.h @@ -232,6 +232,47 @@ BUILT_ASSUME_NONNULL_BEGIN */ - (void)sync:(void (^)(SyncStack * BUILT_NULLABLE_P syncStack, NSError * BUILT_NULLABLE_P error))completionBlock; +/** + The Initial Sync request performs a complete sync of your app data. This is done for seq id. + It returns all the published entries and assets of the specified stack in response. + The response also contains a sync token, which you need to store, + since this token is used to get subsequent delta updates later. + + //Obj-C + [stack syncSeqIdInit:^(SyncStack * _Nullable syncStack, NSError * _Nullable error) { + + }]; + + //Swift + stack.syncSeqIdInit({ ( syncStack:SyncStack, error: NSError) in + + }) + +@param completionBlock called synchronization is done. +*/ +- (void)initSeqSync:(void (^)(SyncStack * BUILT_NULLABLE_P syncStack, NSError * BUILT_NULLABLE_P error))completionBlock; + +/** + You can use the seq_id (that you receive after every sync call) to get the updated content next time. + The seq id is alternative to pagination token where it fetches all the events data in sequence, and the details of the content that was deleted or updated. + + //Obj-C + + NSString *seqId = @"seq_id"; //Seq id + [stack seqId:seqId completion:^(SyncStack * _Nullable syncStack, NSError * _Nullable error) { + + }]; + + //Swift + var seqId = @"seq_id"; //Seq id + stack.seqId(seqId, completion: { ( syncStack:SyncStack, error: NSError) in + + }) + + @param seqId Sync token from where to perform sync + @param completionBlock called synchronization is done. + */ +-(void)syncSeqId:(NSString *)seqId syncToken:(NSString *)syncToken completion:(void (^)(SyncStack * BUILT_NULLABLE_P syncResult, NSError * BUILT_NULLABLE_P error))completionBlock; /** If the result of the initial sync (or subsequent sync) contains more than 100 records, the response would be paginated. It provides pagination token in the response. However, diff --git a/Contentstack/Stack.m b/Contentstack/Stack.m index ec23d84..06069ef 100644 --- a/Contentstack/Stack.m +++ b/Contentstack/Stack.m @@ -167,6 +167,26 @@ -(void)sync:(void (^)(SyncStack * BUILT_NULLABLE_P syncResult, NSError * BUILT_N }]; } +-(void)initSeqSync:(void (^)(SyncStack * BUILT_NULLABLE_P syncResult, NSError * BUILT_NULLABLE_P error))completionBlock { + SyncStack *syncStack = [self getCurrentSyncStack:nil]; + [self syncWithSeqId:syncStack completion:^(SyncStack * _Nullable syncResult, NSError * _Nullable error) { + completionBlock(syncResult, error); + }]; +} + +-(void)syncSeqId:(NSString *)seqId syncToken:(NSString *)syncToken completion:(void (^)(SyncStack * BUILT_NULLABLE_P syncResult, NSError * BUILT_NULLABLE_P error))completionBlock { + SyncStack *syncStack = nil; + if (syncToken) { + syncStack = [self getCurrentSyncStack:@{@"sync_token": syncToken}]; + } else { + syncStack = [self getCurrentSyncStack:@{@"seq_id": seqId}]; + } + + [self syncWithSeqId:syncStack completion:^(SyncStack * _Nullable syncResult, NSError * _Nullable error) { + completionBlock(syncResult, error); + }]; +} + -(void)syncToken:(NSString *)token completion:(void (^)(SyncStack * BUILT_NULLABLE_P syncResult, NSError * BUILT_NULLABLE_P error))completionBlock { SyncStack *syncStack = [self getCurrentSyncStack:@{@"sync_token": token}]; [self sync:syncStack completion:^(SyncStack * _Nullable syncResult, NSError * _Nullable error) { @@ -234,8 +254,6 @@ -(void)syncOnly:(NSString *)contentType locale:(NSString*)locale from:(NSDate *) [self sync:syncStack completion:^(SyncStack * _Nullable syncResult, NSError * _Nullable error) { completionBlock(syncResult, error); }]; - - } -(void)syncOnly:(NSString *)contentType locale:(NSString*)locale from:(NSDate *)date publishType:(PublishType)publishType completion:(void (^)(SyncStack * _Nullable, NSError * _Nullable))completionBlock { @@ -268,6 +286,24 @@ - (void)sync:(SyncStack *)syncResult completion:(void (^)(SyncStack * BUILT_NULL }]; } +- (void)syncWithSeqId:(SyncStack *)syncResult completion:(void (^)(SyncStack * BUILT_NULLABLE_P syncResult, NSError * BUILT_NULLABLE_P error))completionBlock { + NSMutableDictionary *params = [NSMutableDictionary dictionaryWithDictionary:[syncResult getParametersSeqId]]; + if (syncResult.seqId == nil && syncResult.syncToken == nil) { + [params setValue:self.environment forKey:@"environment"]; + } + [self syncCallWithParams:params withCompletion:^(NSDictionary *responseDictionary, NSError *error) { + if (error == nil) { + [syncResult parseSyncResult:responseDictionary]; + completionBlock(syncResult, error); + if (syncResult.hasMorePages) { + [self syncWithSeqId:syncResult completion:completionBlock]; + } + } else { + completionBlock(syncResult, error); + } + }]; +} + - (SyncStack*) getCurrentSyncStack:(NSDictionary*) params { SyncStack *syncResult = [[SyncStack alloc] initWithParmas:params]; return syncResult; diff --git a/Contentstack/SyncStack.h b/Contentstack/SyncStack.h index 8c6990d..eb0a0ff 100644 --- a/Contentstack/SyncStack.h +++ b/Contentstack/SyncStack.h @@ -25,6 +25,10 @@ NS_ASSUME_NONNULL_BEGIN *Readonly property to delta sync. */ @property (nonatomic, copy, readonly) NSString * _Nullable syncToken; +/** + *Readonly property to sync. + */ +@property (nonatomic, copy, readonly) NSString * _Nullable seqId; /** * Readonly property to check skip count */ diff --git a/Contentstack/SyncStack.m b/Contentstack/SyncStack.m index 9dd427f..6a6fb07 100644 --- a/Contentstack/SyncStack.m +++ b/Contentstack/SyncStack.m @@ -8,6 +8,7 @@ #import "SyncStack.h" #import "CSIOInternalHeaders.h" + @implementation SyncStack -(instancetype)initWithParmas:(NSDictionary*) parmas { @@ -17,6 +18,11 @@ -(instancetype)initWithParmas:(NSDictionary*) parmas { if ([[self.params objectForKey:@"sync_token"] isKindOfClass:[NSString class]]) { self.syncToken = [self.params objectForKey:@"sync_token"]; } + if ([[self.params objectForKey:@"seq_id"] + isKindOfClass:[NSString + class]]) { + self.seqId = [self.params objectForKey:@"seq_id"]; + } self.items = [NSArray array]; } return self; @@ -26,6 +32,7 @@ -(void)parseSyncResult:(NSDictionary *)dictionary { if (![dictionary isKindOfClass:[NSNull class]]) { self.syncToken = nil; self.paginationToken = nil; + self.seqId = nil; self.hasMorePages = false; if ([dictionary objectForKey:@"sync_token"]) { self.syncToken = [dictionary objectForKey:@"sync_token"]; @@ -34,6 +41,9 @@ -(void)parseSyncResult:(NSDictionary *)dictionary { self.hasMorePages = true; self.paginationToken = [dictionary objectForKey:@"pagination_token"]; } + if ([dictionary objectForKey:@"last_seq_id"]) { + self.seqId = [dictionary objectForKey:@"last_seq_id"]; + } if ([dictionary objectForKey:@"total_count"]) { self.totalCount = [[dictionary objectForKey:@"total_count"] unsignedIntValue]; } @@ -44,7 +54,10 @@ -(void)parseSyncResult:(NSDictionary *)dictionary { self.limit = [[dictionary objectForKey:@"limit"] unsignedIntValue]; } if ([dictionary objectForKey:@"items"] && [[dictionary objectForKey:@"items"] isKindOfClass:[NSArray class]]) { - self.items = [dictionary objectForKey:@"items"];//[[self.items mutableCopy] arrayByAddingObjectsFromArray:[dictionary objectForKey:@"items"]]; + self.items = [dictionary objectForKey:@"items"]; + if (self.items.count > 0) { + self.hasMorePages = true; + } } } } @@ -61,4 +74,20 @@ -(NSDictionary*)getParameters { } return syncParams; } + +-(NSDictionary*)getParametersSeqId { + NSMutableDictionary *syncParams = [NSMutableDictionary dictionary]; + if (self.seqId != nil) { + [syncParams setValue:self.seqId forKey:@"seq_id"]; + } else if (self.syncToken != nil) { + [syncParams setValue:self.syncToken forKey:@"sync_token"]; + } else { + syncParams = [NSMutableDictionary dictionaryWithDictionary:self.params]; + [syncParams setValue:@"true" forKey:@"seq_id"]; + [syncParams setValue:@"true" forKey:@"init"]; + } + return syncParams; +} + + @end diff --git a/ContentstackInternal/CSIOInternalHeaders.h b/ContentstackInternal/CSIOInternalHeaders.h index 458a057..870ba76 100644 --- a/ContentstackInternal/CSIOInternalHeaders.h +++ b/ContentstackInternal/CSIOInternalHeaders.h @@ -112,9 +112,11 @@ -(instancetype)initWithParmas:(NSDictionary*) parmas; -(void)parseSyncResult:(NSDictionary*) dictionary; -(NSDictionary*)getParameters; +-(NSDictionary*)getParametersSeqId; @property (nonatomic, copy) NSArray *items; @property (nonatomic, copy) NSString *paginationToken; @property (nonatomic, copy) NSString *syncToken; +@property (nonatomic, copy) NSString *seqId; @property (nonatomic, assign) BOOL hasMorePages; @property (nonatomic, assign) unsigned int skip;