diff --git a/CHANGES.rst b/CHANGES.rst index 3deacac31f..5e3af3b620 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -10,6 +10,7 @@ Improvements: * MXRoomSummary: Add a membership property to cache MXRoomState one. * MXRoomSummary: add isConferenceUserRoom. * MXStore: Add Obj-C annotations. +* MXFileStore: Add a setting to set which data to preload ([MXFileStore setPreloadOptions:]). Bug fix: @@ -18,6 +19,7 @@ API break: * MXCall: callee access is now asynchronous. * MXRoomState: Remove displayName property. Use MXRoomSummary.displayName instead. * MXRoomState: Create a MXRoomMembers property. All members getter methods has been to the new class. +* MXStore: Make the stateOfRoom method asynchronous. Changes in Matrix iOS SDK in 0.10.12 (2018-05-31) =============================================== diff --git a/MatrixSDK/Data/MXRoom.h b/MatrixSDK/Data/MXRoom.h index 119c5c40cf..eafda62760 100644 --- a/MatrixSDK/Data/MXRoom.h +++ b/MatrixSDK/Data/MXRoom.h @@ -179,7 +179,7 @@ FOUNDATION_EXPORT NSString *const kMXRoomDidFlushDataNotification; @param store the store to mount data from and to store live data to. @param roomId the id of the room. - @param mxSession the session to use. + @param matrixSession the session to use. @return the new instance. */ + (id)loadRoomFromStore:(id)store withRoomId:(NSString *)roomId matrixSession:(MXSession *)matrixSession; diff --git a/MatrixSDK/Data/MXRoom.m b/MatrixSDK/Data/MXRoom.m index 555072b054..59892e1a39 100644 --- a/MatrixSDK/Data/MXRoom.m +++ b/MatrixSDK/Data/MXRoom.m @@ -57,9 +57,6 @@ The list of room operations (sending of text, images...) that must be sent FIFO queue of objects waiting for [self liveTimeline:]. */ NSMutableArray *pendingLiveTimelineRequesters; - - // @TODO(async-state): For dev - BOOL __forceAsyncLoad; } @end @@ -80,7 +77,6 @@ - (instancetype)init _directUserId = nil; needToLoadLiveTimeline = NO; - __forceAsyncLoad = YES; } return self; @@ -180,26 +176,18 @@ - (MXRoomSummary *)summary - (void)liveTimeline:(void (^)(MXEventTimeline *))onComplete { // Is timelime ready? - if (needToLoadLiveTimeline || pendingLiveTimelineRequesters || __forceAsyncLoad) + if (needToLoadLiveTimeline || pendingLiveTimelineRequesters) { - __forceAsyncLoad = NO; - BOOL __needToLoadLiveTimeline = needToLoadLiveTimeline; - // Queue the requester if (!pendingLiveTimelineRequesters) { pendingLiveTimelineRequesters = [NSMutableArray array]; MXWeakify(self); - // @TODO(async-state): dispatch_async is just for testing that the async access works - dispatch_async(dispatch_get_main_queue(), ^{ + [MXRoomState loadRoomStateFromStore:self.mxSession.store withRoomId:self.roomId matrixSession:self.mxSession onComplete:^(MXRoomState *roomState) { MXStrongifyAndReturnIfNil(self); - if (__needToLoadLiveTimeline) - { - MXRoomState *roomState = [MXRoomState loadRoomStateFromStore:self.mxSession.store withRoomId:self.roomId matrixSession:self.mxSession]; - [self->liveTimeline setState:roomState]; - } + [self->liveTimeline setState:roomState]; // Provide the timelime to pending requesters NSArray *liveTimelineRequesters = [self->pendingLiveTimelineRequesters copy]; @@ -210,7 +198,7 @@ - (void)liveTimeline:(void (^)(MXEventTimeline *))onComplete onRequesterComplete(self->liveTimeline); } NSLog(@"[MXRoom] liveTimeline loaded. Pending requesters: %@", @(liveTimelineRequesters.count)); - }); + }]; } [pendingLiveTimelineRequesters addObject:onComplete]; diff --git a/MatrixSDK/Data/MXRoomState.h b/MatrixSDK/Data/MXRoomState.h index 3fb1590b12..61cec67b7e 100644 --- a/MatrixSDK/Data/MXRoomState.h +++ b/MatrixSDK/Data/MXRoomState.h @@ -182,11 +182,12 @@ Use MXRoomSummary.displayname to get a computed room display name. @param store the store to mount data from and to store live data to. @param roomId the id of the room. @param matrixSession the session to use. - @return the new instance. + @param onComplete the block providing the new instance. */ -+ (id)loadRoomStateFromStore:(id)store ++ (void)loadRoomStateFromStore:(id)store withRoomId:(NSString *)roomId - matrixSession:(MXSession *)matrixSession; + matrixSession:(MXSession *)matrixSession + onComplete:(void (^)(MXRoomState *roomState))onComplete; /** Create a `MXRoomState` instance used as a back state of a room. diff --git a/MatrixSDK/Data/MXRoomState.m b/MatrixSDK/Data/MXRoomState.m index 225eb4c1b4..265cea8fd4 100644 --- a/MatrixSDK/Data/MXRoomState.m +++ b/MatrixSDK/Data/MXRoomState.m @@ -105,16 +105,20 @@ - (id)initWithRoomId:(NSString*)roomId return self; } -+ (id)loadRoomStateFromStore:(id)store withRoomId:(NSString *)roomId matrixSession:(MXSession *)matrixSession ++ (void)loadRoomStateFromStore:(id)store + withRoomId:(NSString *)roomId + matrixSession:(MXSession *)matrixSession + onComplete:(void (^)(MXRoomState *roomState))onComplete { - MXRoomState *state = [[MXRoomState alloc] initWithRoomId:roomId andMatrixSession:matrixSession andDirection:YES]; - if (state) + MXRoomState *roomState = [[MXRoomState alloc] initWithRoomId:roomId andMatrixSession:matrixSession andDirection:YES]; + if (roomState) { - NSArray *stateEvents = [store stateOfRoom:roomId]; - [state handleStateEvents:stateEvents]; - } + [store stateOfRoom:roomId success:^(NSArray * _Nonnull stateEvents) { + [roomState handleStateEvents:stateEvents]; - return state; + onComplete(roomState); + } failure:nil]; + } } - (id)initBackStateWith:(MXRoomState*)state diff --git a/MatrixSDK/Data/Store/MXFileStore/MXFileStore.h b/MatrixSDK/Data/Store/MXFileStore/MXFileStore.h index 556dc4867a..44f245ab6d 100644 --- a/MatrixSDK/Data/Store/MXFileStore/MXFileStore.h +++ b/MatrixSDK/Data/Store/MXFileStore/MXFileStore.h @@ -1,6 +1,7 @@ /* Copyright 2014 OpenMarket Ltd Copyright 2017 Vector Creations Ltd + Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,6 +20,21 @@ NS_ASSUME_NONNULL_BEGIN +/** + Options for preloading data during the `[MXStore openWithCredentials:]` operation. + */ +typedef NS_OPTIONS(NSInteger, MXFileStorePreloadOptions) +{ + // Preload rooms summaries + MXFileStorePreloadOptionRoomSummary = 0x1, + + // Preload rooms states + MXFileStorePreloadOptionRoomState = 0x2, + + // Preload rooms account data + MXFileStorePreloadOptionRoomAccountData = 0x4 +}; + /** `MXFileStore` extends MXMemoryStore by adding permanent storage. @@ -86,6 +102,15 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)diskUsageWithBlock:(void(^)(NSUInteger diskUsage))block; +/** + Set the preload options for the file store. + + These options are used in the `[MXStore openWithCredentials:]`. + + @param preloadOptions bit flags of `MXFileStorePreloadOptions`. + */ ++ (void)setPreloadOptions:(MXFileStorePreloadOptions)preloadOptions; + #pragma mark - Async API /** @@ -126,16 +151,6 @@ NS_ASSUME_NONNULL_BEGIN - (void)asyncRoomsSummaries:(void (^)(NSArray *roomsSummaries))success failure:(nullable void (^)(NSError *error))failure; -/** - Get the stored room state for a specific room. - @param roomId the Id of the room - @param success A block object called when the operation succeeds. - @param failure A block object called when the operation fails. - */ -- (void)asyncStateEventsOfRoom:(NSString *)roomId - success:(void (^)(NSArray * _Nonnull stateEvents))success - failure:(nullable void (^)(NSError * _Nonnull error))failure; - /** Get the stored account data for a specific room. diff --git a/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m b/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m index c6babc4d7d..4339e38d29 100644 --- a/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m +++ b/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m @@ -1,6 +1,7 @@ /* Copyright 2014 OpenMarket Ltd Copyright 2017 Vector Creations Ltd + Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -41,6 +42,8 @@ static NSString *const kMXFileStoreRoomAccountDataFile = @"accountData"; static NSString *const kMXFileStoreRoomReadReceiptsFile = @"readReceipts"; +static NSUInteger preloadOptions; + @interface MXFileStore () { // Meta data about the store. It is defined only if the passed MXCredentials contains all information. @@ -112,6 +115,16 @@ @interface MXFileStore () @implementation MXFileStore ++ (void)initialize +{ + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + + // By default, we do not need to preload rooms states now + preloadOptions = MXFileStorePreloadOptionRoomSummary | MXFileStorePreloadOptionRoomAccountData; + }); +} + - (instancetype)init; { self = [super init]; @@ -211,9 +224,18 @@ - (void)openWithCredentials:(MXCredentials*)someCredentials onComplete:(void (^) NSLog(@"[MXFileStore] Start data loading from files"); [self loadRoomsMessages]; - [self preloadRoomsStates]; - [self preloadRoomsSummaries]; - [self preloadRoomsAccountData]; + if (preloadOptions & MXFileStorePreloadOptionRoomState) + { + [self preloadRoomsStates]; + } + if (preloadOptions & MXFileStorePreloadOptionRoomSummary) + { + [self preloadRoomsSummaries]; + } + if (preloadOptions & MXFileStorePreloadOptionRoomAccountData) + { + [self preloadRoomsAccountData]; + } [self loadReceipts]; [self loadUsers]; [self loadGroups]; @@ -276,6 +298,11 @@ - (void)diskUsageWithBlock:(void (^)(NSUInteger))block } ++ (void)setPreloadOptions:(MXFileStorePreloadOptions)thePreloadOptions +{ + preloadOptions = thePreloadOptions; +} + #pragma mark - MXStore - (void)storeEventForRoom:(NSString*)roomId event:(MXEvent*)event direction:(MXTimelineDirection)direction { @@ -401,6 +428,18 @@ - (void)storeStateForRoom:(NSString*)roomId stateEvents:(NSArray*)stateEvents roomsToCommitForState[roomId] = stateEvents; } +- (void)stateOfRoom:(NSString *)roomId success:(void (^)(NSArray * _Nonnull))success failure:(void (^)(NSError * _Nonnull))failure +{ + dispatch_async(dispatchQueue, ^{ + + NSArray *stateEvents = [self stateOfRoom:roomId]; + + dispatch_async(dispatch_get_main_queue(), ^{ + success(stateEvents); + }); + }); +} + - (NSArray*)stateOfRoom:(NSString *)roomId { // First, try to get the state from the cache @@ -1752,18 +1791,6 @@ - (void)asyncRoomsSummaries:(void (^)(NSArray * _Nonnull))succe }); } -- (void)asyncStateEventsOfRoom:(NSString *)roomId success:(void (^)(NSArray * _Nonnull))success failure:(nullable void (^)(NSError * _Nonnull))failure -{ - dispatch_async(dispatchQueue, ^{ - - NSArray *stateEvents = [self stateOfRoom:roomId]; - - dispatch_async(dispatch_get_main_queue(), ^{ - success(stateEvents); - }); - }); -} - - (void)asyncAccountDataOfRoom:(NSString *)roomId success:(void (^)(MXRoomAccountData * _Nonnull))success failure:(nullable void (^)(NSError * _Nonnull))failure { dispatch_async(dispatchQueue, ^{ diff --git a/MatrixSDK/Data/Store/MXStore.h b/MatrixSDK/Data/Store/MXStore.h index 0693260ede..d8db0c67d1 100644 --- a/MatrixSDK/Data/Store/MXStore.h +++ b/MatrixSDK/Data/Store/MXStore.h @@ -310,10 +310,12 @@ Note: this method is required in permanent storage implementation. @param roomId the id of the room. - - @return the stored state events that define the room state. + @param success A block object called when the operation succeeds. + @param failure A block object called when the operation fails. */ -- (NSArray * _Nullable)stateOfRoom:(nonnull NSString*)roomId; +- (void)stateOfRoom:(nonnull NSString *)roomId + success:(nonnull void (^)(NSArray * _Nonnull stateEvents))success + failure:(nullable void (^)(NSError * _Nonnull error))failure; #pragma mark - Room summary diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index 8bef1380e6..8b9623d8bf 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -267,7 +267,7 @@ -(void)setStore:(id)store success:(void (^)(void))onStoreDataReady fail // A permanent MXStore must implement these methods: NSParameterAssert([_store respondsToSelector:@selector(rooms)]); NSParameterAssert([_store respondsToSelector:@selector(storeStateForRoom:stateEvents:)]); - NSParameterAssert([_store respondsToSelector:@selector(stateOfRoom:)]); + NSParameterAssert([_store respondsToSelector:@selector(stateOfRoom:success:failure:)]); NSParameterAssert([_store respondsToSelector:@selector(summaryOfRoom:)]); }