From 410df78850e30583058dbef56584166a71a16ef9 Mon Sep 17 00:00:00 2001 From: manuroe Date: Mon, 9 May 2016 16:57:50 +0200 Subject: [PATCH 01/19] Ignored users: BF: kMXSessionIgnoredUsersDidChangeNotification was sometimes not sent --- MatrixSDK/MXSession.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index 95e1f598c3..d4ab07590f 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -620,13 +620,13 @@ - (void)serverSyncWithServerTimeout:(NSUInteger)serverTimeout NSCountedSet *set1 = [NSCountedSet setWithArray:_ignoredUsers]; NSCountedSet *set2 = [NSCountedSet setWithArray:newIgnoredUsers]; - // Testing _ignoredUsers allow to filter first /sync - BOOL notify = _ignoredUsers && ![set1 isEqualToSet:set2]; + // Do not notify for the first /sync + BOOL notify = !isInitialSync && ![set1 isEqualToSet:set2]; _ignoredUsers = newIgnoredUsers; // Report the change - if (notify) + if (!isInitialSync) { [[NSNotificationCenter defaultCenter] postNotificationName:kMXSessionIgnoredUsersDidChangeNotification object:self From 2b14c054761f9f36d9f696b5870ca129393122f2 Mon Sep 17 00:00:00 2001 From: giomfo Date: Fri, 13 May 2016 22:39:27 +0200 Subject: [PATCH 02/19] Bug Fix: all blank after upgrade; no spinner https://github.com/vector-im/vector-ios/issues/311 --- MatrixSDK/MXSession.h | 15 ++++++++++++--- MatrixSDK/MXSession.m | 32 ++++++++++++++++++++++++-------- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/MatrixSDK/MXSession.h b/MatrixSDK/MXSession.h index dabd84efea..f3c3a43543 100644 --- a/MatrixSDK/MXSession.h +++ b/MatrixSDK/MXSession.h @@ -50,7 +50,7 @@ typedef enum : NSUInteger @discussion It is either doing a global initialSync or restarting the events stream from the previous known position. This position is provided by the store for a cold start or by the `MXSession` - itself when [MXSession resume] is called. + itself when [MXSession resume:] is called. */ MXSessionStateSyncInProgress, @@ -77,7 +77,15 @@ typedef enum : NSUInteger /** The session has been paused. */ - MXSessionStatePaused + MXSessionStatePaused, + + /** + The initial sync failed. + + @discussion + The Matrix session will stay in this state until a new call of [MXSession start:failure:]. + */ + MXSessionStateInitialSyncFailed } MXSessionState; @@ -225,7 +233,8 @@ FOUNDATION_EXPORT NSString *const kMXSessionNoRoomTag; will resume the events streaming from where it had been stopped the time before. @param onServerSyncDone A block object called when the data is up-to-date with the server. - @param failure A block object called when the operation fails. + @param failure A block object called when the operation fails. In case of failure during the + initial sync the session state is MXSessionStateInitialSyncFailed. */ - (void)start:(void (^)())onServerSyncDone failure:(void (^)(NSError *error))failure; diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index d4ab07590f..45f384f776 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -259,12 +259,18 @@ - (void)startWithMessagesLimit:(NSUInteger)messagesLimit // Set the store before going further __weak typeof(self) weakSelf = self; + [self setStore:store success:^{ // Then, start again [weakSelf startWithMessagesLimit:messagesLimit onServerSyncDone:onServerSyncDone failure:failure]; - } failure:failure]; + } failure:^(NSError *error) { + + [self setState:MXSessionStateInitialSyncFailed]; + failure(error); + + }]; return; } @@ -302,19 +308,30 @@ - (void)startWithMessagesLimit:(NSUInteger)messagesLimit [_notificationCenter refreshRules:^{ // Initial server sync - [self serverSyncWithServerTimeout:0 success:onServerSyncDone failure:failure clientTimeout:CLIENT_TIMEOUT_MS setPresence:nil]; + [self serverSyncWithServerTimeout:0 success:onServerSyncDone failure:^(NSError *error) { + + [self setState:MXSessionStateInitialSyncFailed]; + failure(error); + + } clientTimeout:CLIENT_TIMEOUT_MS setPresence:nil]; } failure:^(NSError *error) { - [self setState:MXSessionStateHomeserverNotReachable]; + + [self setState:MXSessionStateInitialSyncFailed]; failure(error); + }]; } failure:^(NSError *error) { - [self setState:MXSessionStateHomeserverNotReachable]; + + [self setState:MXSessionStateInitialSyncFailed]; failure(error); + }]; } failure:^(NSError *error) { - [self setState:MXSessionStateHomeserverNotReachable]; + + [self setState:MXSessionStateInitialSyncFailed]; failure(error); + }]; } } @@ -748,9 +765,6 @@ - (void)serverSyncWithServerTimeout:(NSUInteger)serverTimeout // Check whether the caller wants to handle error himself if (failure) { - // Inform the app there is a problem with the connection to the homeserver - [self setState:MXSessionStateHomeserverNotReachable]; - failure(error); } else @@ -799,6 +813,7 @@ - (void)serverSyncWithServerTimeout:(NSUInteger)serverTimeout if (eventStreamRequest) { NSLog(@"[MXSession] Retry resuming events stream"); + [self setState:MXSessionStateSyncInProgress]; [self serverSyncWithServerTimeout:serverTimeout success:success failure:nil clientTimeout:CLIENT_TIMEOUT_MS setPresence:nil]; } }); @@ -814,6 +829,7 @@ - (void)serverSyncWithServerTimeout:(NSUInteger)serverTimeout [[NSNotificationCenter defaultCenter] removeObserver:reachabilityObserver]; NSLog(@"[MXSession] Retry resuming events stream"); + [self setState:MXSessionStateSyncInProgress]; [self serverSyncWithServerTimeout:serverTimeout success:success failure:nil clientTimeout:CLIENT_TIMEOUT_MS setPresence:nil]; } }]; From ee06c794486cf9ec5c7ae8008c930cf89b126275 Mon Sep 17 00:00:00 2001 From: giomfo Date: Tue, 17 May 2016 13:47:05 +0200 Subject: [PATCH 03/19] MXSession: fix warning --- MatrixSDK/MXSession.m | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index 45f384f776..0871af61e8 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -263,11 +263,13 @@ - (void)startWithMessagesLimit:(NSUInteger)messagesLimit [self setStore:store success:^{ // Then, start again - [weakSelf startWithMessagesLimit:messagesLimit onServerSyncDone:onServerSyncDone failure:failure]; + __strong __typeof(weakSelf)strongSelf = weakSelf; + [strongSelf startWithMessagesLimit:messagesLimit onServerSyncDone:onServerSyncDone failure:failure]; } failure:^(NSError *error) { - [self setState:MXSessionStateInitialSyncFailed]; + __strong __typeof(weakSelf)strongSelf = weakSelf; + [strongSelf setState:MXSessionStateInitialSyncFailed]; failure(error); }]; From 7d17d1fa5646d230d421b8a7546702b61e21ac2c Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 17 May 2016 13:58:41 +0200 Subject: [PATCH 04/19] MXSession: fix warning --- MatrixSDK/MXSession.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index 0871af61e8..40727f153f 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -645,7 +645,7 @@ - (void)serverSyncWithServerTimeout:(NSUInteger)serverTimeout _ignoredUsers = newIgnoredUsers; // Report the change - if (!isInitialSync) + if (notify) { [[NSNotificationCenter defaultCenter] postNotificationName:kMXSessionIgnoredUsersDidChangeNotification object:self From e283c09ccd97fc311cc3d2634f0894ff6680fd0e Mon Sep 17 00:00:00 2001 From: manuroe Date: Wed, 18 May 2016 15:04:25 +0200 Subject: [PATCH 05/19] Tests improvements: Prevent the test suite from breaking because one test fails. This is done by replacing NSAssert by XCTFailure. --- MatrixSDKTests/MXEventTimelineTests.m | 3 +- MatrixSDKTests/MXMyUserTests.m | 9 +- MatrixSDKTests/MXNotificationCenterTests.m | 49 ++++--- MatrixSDKTests/MXRestClientNoAuthAPITests.m | 2 +- MatrixSDKTests/MXRestClientTests.m | 12 +- MatrixSDKTests/MXRoomMemberTests.m | 2 +- MatrixSDKTests/MXRoomStateDynamicTests.m | 56 +++++--- MatrixSDKTests/MXRoomStateTests.m | 37 +++-- MatrixSDKTests/MXRoomTests.m | 22 ++- MatrixSDKTests/MXSessionTests.m | 120 ++++++++++------ MatrixSDKTests/MXStoreTests.m | 147 +++++++++++++------- MatrixSDKTests/MXUserTests.m | 36 +++-- MatrixSDKTests/MXVoIPTests.m | 3 +- 13 files changed, 327 insertions(+), 171 deletions(-) diff --git a/MatrixSDKTests/MXEventTimelineTests.m b/MatrixSDKTests/MXEventTimelineTests.m index fca83e57f9..78aa180f90 100644 --- a/MatrixSDKTests/MXEventTimelineTests.m +++ b/MatrixSDKTests/MXEventTimelineTests.m @@ -69,7 +69,8 @@ - (void)doTestWithARoomOf41Messages:(XCTestCase*)testCase readyToTest:(void (^)( }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; }]; diff --git a/MatrixSDKTests/MXMyUserTests.m b/MatrixSDKTests/MXMyUserTests.m index 22e7136527..1dab266a48 100644 --- a/MatrixSDKTests/MXMyUserTests.m +++ b/MatrixSDKTests/MXMyUserTests.m @@ -96,7 +96,8 @@ - (void)testSetDisplayName }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; @@ -130,7 +131,8 @@ - (void)testSetAvatarURL }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; @@ -167,7 +169,8 @@ - (void)testSetPresence }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; diff --git a/MatrixSDKTests/MXNotificationCenterTests.m b/MatrixSDKTests/MXNotificationCenterTests.m index 905f288d97..a3e0b2fadd 100644 --- a/MatrixSDKTests/MXNotificationCenterTests.m +++ b/MatrixSDKTests/MXNotificationCenterTests.m @@ -72,7 +72,8 @@ - (void)testNotificationCenterRulesReady [expectation fulfill]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -86,6 +87,7 @@ - (void)testNoNotificationsOnUserEvents [mxSession.notificationCenter listenToNotifications:^(MXEvent *event, MXRoomState *roomState, MXPushRule *rule) { XCTFail(@"Events from the user should not be notified. event: %@\n rule: %@", event, rule); + [expectation fulfill]; }]; @@ -99,7 +101,8 @@ - (void)testNoNotificationsOnUserEvents }); } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -129,11 +132,13 @@ - (void)testNoNotificationsOnPresenceOrTypingEvents }); } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; @@ -163,7 +168,8 @@ - (void)testDefaultPushOnAllNonYouMessagesRule [aliceRestClient sendTextMessageToRoom:roomId text:@"a message" success:^(NSString *eventId) { } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; @@ -173,7 +179,8 @@ - (void)testDefaultPushOnAllNonYouMessagesRule [room inviteUser:carolId success:^{ } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; }; @@ -206,7 +213,8 @@ - (void)testDefaultContentCondition [aliceRestClient sendTextMessageToRoom:roomId text:messageFromAlice success:^(NSString *eventId) { } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; @@ -215,7 +223,8 @@ - (void)testDefaultContentCondition [room inviteUser:carolId success:^{ } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; @@ -253,15 +262,18 @@ - (void)testDefaultDisplayNameCondition [roomBobSide sendTextMessage:messageFromBob success:^(NSString *eventId) { } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; @@ -294,7 +306,8 @@ - (void)testDefaultRoomMemberCountCondition [aliceRestClient sendTextMessageToRoom:roomId text:messageFromAlice success:^(NSString *eventId) { } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; @@ -326,7 +339,8 @@ - (void)testRemoveListener }); } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; @@ -371,15 +385,18 @@ - (void)testRuleMatchingEvent [roomBobSide sendTextMessage:messageFromBob success:^(NSString *eventId) { } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; diff --git a/MatrixSDKTests/MXRestClientNoAuthAPITests.m b/MatrixSDKTests/MXRestClientNoAuthAPITests.m index 1cc526e357..895abf721f 100644 --- a/MatrixSDKTests/MXRestClientNoAuthAPITests.m +++ b/MatrixSDKTests/MXRestClientNoAuthAPITests.m @@ -73,7 +73,7 @@ - (void)createTestAccount:(void (^)())onReady } else { - NSAssert(NO, @"Cannot create the test account"); + XCTFail(@"Cannot create the test account"); } }]; mxRestClient.apiPathPrefix = kMXAPIPrefixPathR0; diff --git a/MatrixSDKTests/MXRestClientTests.m b/MatrixSDKTests/MXRestClientTests.m index 7dcb2373fc..4ab131beff 100644 --- a/MatrixSDKTests/MXRestClientTests.m +++ b/MatrixSDKTests/MXRestClientTests.m @@ -237,7 +237,7 @@ - (void)testInviteUserToRoom [expectation fulfill]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot check test result - error: %@", error); + XCTFail(@"Cannot check test result - error: %@", error); [expectation fulfill]; }]; @@ -279,7 +279,7 @@ - (void)testKickUserFromRoom [expectation fulfill]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot check test result - error: %@", error); + XCTFail(@"Cannot check test result - error: %@", error); [expectation fulfill]; }]; @@ -319,7 +319,7 @@ - (void)testBanUserInRoom [expectation fulfill]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot check test result - error: %@", error); + XCTFail(@"Cannot check test result - error: %@", error); [expectation fulfill]; }]; @@ -484,7 +484,8 @@ - (void)testRedactEvent }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -556,7 +557,8 @@ - (void)testContextOfEvent }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } diff --git a/MatrixSDKTests/MXRoomMemberTests.m b/MatrixSDKTests/MXRoomMemberTests.m index 7142f572aa..1bf3dd22ad 100644 --- a/MatrixSDKTests/MXRoomMemberTests.m +++ b/MatrixSDKTests/MXRoomMemberTests.m @@ -67,7 +67,7 @@ - (void)testKickedMember [expectation fulfill]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot check test result - error: %@", error); + XCTFail(@"Cannot check test result - error: %@", error); [expectation fulfill]; }]; diff --git a/MatrixSDKTests/MXRoomStateDynamicTests.m b/MatrixSDKTests/MXRoomStateDynamicTests.m index 7cac8c9b06..a8188461a2 100644 --- a/MatrixSDKTests/MXRoomStateDynamicTests.m +++ b/MatrixSDKTests/MXRoomStateDynamicTests.m @@ -60,7 +60,7 @@ - (void)tearDown 5 - Bob changes the room topic to "Topic #2" 6 - Bob: "Bonjour" */ --(void)createScenario1:(MXRestClient*)bobRestClient inRoom:(NSString*)roomId onComplete:(void(^)())onComplete +-(void)createScenario1:(MXRestClient*)bobRestClient inRoom:(NSString*)roomId expectation:(XCTestExpectation*)expectation onComplete:(void(^)())onComplete { __block MXRestClient *bobRestClient2 = bobRestClient; @@ -78,23 +78,28 @@ -(void)createScenario1:(MXRestClient*)bobRestClient inRoom:(NSString*)roomId onC onComplete(); } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } @@ -102,7 +107,7 @@ - (void)testBackPaginationForScenario1 { [matrixSDKTestsData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { - [self createScenario1:bobRestClient inRoom:roomId onComplete:^{ + [self createScenario1:bobRestClient inRoom:roomId expectation:expectation onComplete:^{ mxSession = [[MXSession alloc] initWithMatrixRestClient:bobRestClient]; @@ -256,13 +261,14 @@ - (void)testLiveEventsForScenario1 default: XCTFail(@"No more events are expected"); + [expectation fulfill]; break; } }]; // Send events of the scenario - [self createScenario1:bobRestClient inRoom:roomId onComplete:^{ + [self createScenario1:bobRestClient inRoom:roomId expectation:expectation onComplete:^{ }]; @@ -291,7 +297,7 @@ - (void)testLiveEventsForScenario1 9 - Alice leaves the room 10 - Bob: "Good bye" */ -- (void)createScenario2:(MXRestClient*)bobRestClient inRoom:(NSString*)roomId onComplete:(void(^)(MXRestClient *aliceRestClient))onComplete +- (void)createScenario2:(MXRestClient*)bobRestClient inRoom:(NSString*)roomId expectation:(XCTestExpectation*)expectation onComplete:(void(^)(MXRestClient *aliceRestClient))onComplete { [bobRestClient sendTextMessageToRoom:roomId text:@"Hello world" success:^(NSString *eventId) { @@ -318,40 +324,49 @@ - (void)createScenario2:(MXRestClient*)bobRestClient inRoom:(NSString*)roomId on onComplete(aliceRestClient2); } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } @@ -360,7 +375,7 @@ - (void)testBackPaginationForScenario2 { [matrixSDKTestsData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { - [self createScenario2:bobRestClient inRoom:roomId onComplete:^(MXRestClient *aliceRestClient) { + [self createScenario2:bobRestClient inRoom:roomId expectation:expectation onComplete:^(MXRestClient *aliceRestClient) { mxSession = [[MXSession alloc] initWithMatrixRestClient:bobRestClient]; @@ -690,13 +705,14 @@ - (void)testLiveEventsForScenario2 default: XCTFail(@"No more events are expected"); + [expectation fulfill]; break; } }]; // Send events of the scenario - [self createScenario2:bobRestClient inRoom:roomId onComplete:^(MXRestClient *aliceRestClient) { + [self createScenario2:bobRestClient inRoom:roomId expectation:expectation onComplete:^(MXRestClient *aliceRestClient) { }]; diff --git a/MatrixSDKTests/MXRoomStateTests.m b/MatrixSDKTests/MXRoomStateTests.m index 3dfb8983a4..cef62d0e36 100644 --- a/MatrixSDKTests/MXRoomStateTests.m +++ b/MatrixSDKTests/MXRoomStateTests.m @@ -417,7 +417,7 @@ - (void)testDisplayName2 5 - Bob invites Alice 6 - Bob: "I wait for Alice" */ -- (void)createInviteByUserScenario:(MXRestClient*)bobRestClient inRoom:(NSString*)roomId inviteAlice:(BOOL)inviteAlice onComplete:(void(^)())onComplete +- (void)createInviteByUserScenario:(MXRestClient*)bobRestClient inRoom:(NSString*)roomId inviteAlice:(BOOL)inviteAlice expectation:(XCTestExpectation*)expectation onComplete:(void(^)())onComplete { [bobRestClient sendTextMessageToRoom:roomId text:@"Hello world" success:^(NSString *eventId) { @@ -438,11 +438,13 @@ - (void)createInviteByUserScenario:(MXRestClient*)bobRestClient inRoom:(NSString onComplete(); } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } else @@ -452,15 +454,18 @@ - (void)createInviteByUserScenario:(MXRestClient*)bobRestClient inRoom:(NSString }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } @@ -468,7 +473,7 @@ - (void)testInviteByOtherInInitialSync { [matrixSDKTestsData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { - [self createInviteByUserScenario:bobRestClient inRoom:roomId inviteAlice:YES onComplete:^{ + [self createInviteByUserScenario:bobRestClient inRoom:roomId inviteAlice:YES expectation:expectation onComplete:^{ [matrixSDKTestsData doMXRestClientTestWithAlice:nil readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { @@ -555,7 +560,7 @@ - (void)testInviteByOtherInLive }]; - [self createInviteByUserScenario:bobRestClient inRoom:roomId inviteAlice:YES onComplete:^{ + [self createInviteByUserScenario:bobRestClient inRoom:roomId inviteAlice:YES expectation:expectation onComplete:^{ // Make sure we have tested something XCTAssertNotNil(newRoom); @@ -578,7 +583,7 @@ - (void)testMXRoomJoin { [matrixSDKTestsData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { - [self createInviteByUserScenario:bobRestClient inRoom:roomId inviteAlice:YES onComplete:^{ + [self createInviteByUserScenario:bobRestClient inRoom:roomId inviteAlice:YES expectation:expectation onComplete:^{ [matrixSDKTestsData doMXRestClientTestWithAlice:nil readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { @@ -644,7 +649,7 @@ - (void)testMXSessionJoinOnPublicRoom { [matrixSDKTestsData doMXRestClientTestWithBobAndAPublicRoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { - [self createInviteByUserScenario:bobRestClient inRoom:roomId inviteAlice:NO onComplete:^{ + [self createInviteByUserScenario:bobRestClient inRoom:roomId inviteAlice:NO expectation:expectation onComplete:^{ [matrixSDKTestsData doMXRestClientTestWithAlice:nil readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { @@ -790,15 +795,18 @@ - (void)testRoomStateWhenARoomHasBeenJoinedOnAnotherMatrixClient [bobRestClient sendTextMessageToRoom:roomId text:@"Hi Alice 2!" success:^(NSString *eventId) { } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -847,7 +855,8 @@ - (void)testRoomStateWhenARoomHasBeenJoinedOnAnotherMatrixClientAndNotifications }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } diff --git a/MatrixSDKTests/MXRoomTests.m b/MatrixSDKTests/MXRoomTests.m index 0c4c5cea37..37354cb763 100644 --- a/MatrixSDKTests/MXRoomTests.m +++ b/MatrixSDKTests/MXRoomTests.m @@ -100,7 +100,8 @@ - (void)testListenerForAllLiveEvents checkEventIDs(); } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; @@ -154,7 +155,8 @@ - (void)testListenerForRoomMessageLiveEvents checkEventIDs(); } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; @@ -223,11 +225,13 @@ - (void)testJoin } failure:^(NSError *error) {; - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; }]; @@ -257,7 +261,8 @@ - (void)testSetPowerLevelOfUser }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -277,6 +282,7 @@ - (void)testPaginateBackMessagesCancel eventCount++; XCTFail(@"We should not receive events. Received: %@", event); + [expectation fulfill]; }]; @@ -329,7 +335,8 @@ - (void)testTypingUsersNotifications }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -413,7 +420,8 @@ - (void)testReplaceTag [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } diff --git a/MatrixSDKTests/MXSessionTests.m b/MatrixSDKTests/MXSessionTests.m index 10003ffe85..6bffa76d1e 100644 --- a/MatrixSDKTests/MXSessionTests.m +++ b/MatrixSDKTests/MXSessionTests.m @@ -81,7 +81,8 @@ - (void)testRoomWithAlias }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -253,7 +254,8 @@ - (void)testListenerForAllLiveEvents }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -290,7 +292,8 @@ - (void)testListenerForRoomMessageOnly }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -343,11 +346,13 @@ - (void)testListenerForPresence [aliceRestClient sendTextMessageToRoom:roomId text:@"Hi Bob!" success:^(NSString *eventId) { } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -364,18 +369,21 @@ - (void)testClose [mxSession listenToEvents:^(MXEvent *event, MXTimelineDirection direction, id customObject) { XCTFail(@"We should not receive events after closing the session. Received: %@", event); + [expectation fulfill]; }]; MXRoom *room = [mxSession roomWithRoomId:roomId]; XCTAssert(room); [room.liveTimeline listenToEvents:^(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState) { XCTFail(@"We should not receive events after closing the session. Received: %@", event); + [expectation fulfill]; }]; MXUser *bob = [mxSession userWithUserId:bobRestClient.credentials.userId]; XCTAssert(bob); [bob listenToUserUpdate:^(MXEvent *event) { XCTFail(@"We should not receive events after closing the session. Received: %@", event); + [expectation fulfill]; }]; @@ -396,12 +404,14 @@ - (void)testClose [expectation performSelector:@selector(fulfill) withObject:nil afterDelay:5]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -437,13 +447,16 @@ - (void)testCloseWithMXMemoryStore }); } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -490,7 +503,8 @@ - (void)testPauseResume [bobRestClient sendTextMessageToRoom:roomId text:@"A message" success:^(NSString *eventId) { } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; // Resume the MXSession in 3 secs @@ -510,7 +524,8 @@ - (void)testPauseResume }); } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -573,7 +588,8 @@ - (void)testPauseResumeOnNothingNew }); } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -674,7 +690,8 @@ - (void)testPrivateOneToOneRoomWithUserId [expectation fulfill]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -731,12 +748,14 @@ - (void)testNewRoomNotificationOnCreatingPublicRoom [mxSession.matrixRestClient createRoom:nil visibility:kMXRoomVisibilityPublic roomAlias:nil topic:nil success:^(MXCreateRoomResponse *response) { } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; @@ -769,7 +788,8 @@ - (void)testNewRoomNotificationOnJoiningPublicRoom }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; @@ -808,7 +828,8 @@ - (void)testMXRoomInitialSyncNotificationOnJoiningPublicRoom }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; @@ -873,22 +894,28 @@ - (void)doRoomByTagsOrderTest:(XCTestCase*)testCase withOrder1:(NSString*)order1 }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -941,16 +968,20 @@ - (void)testTagRoomsWithSameOrder }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -991,14 +1022,17 @@ - (void)testRoomByTagsAndNoRoomTag } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -1059,22 +1093,28 @@ - (void)testTagOrderToBeAtIndex }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -1137,11 +1177,13 @@ - (void)testInvitedRooms [aliceRestClient inviteUser:bobSession.matrixRestClient.credentials.userId toRoom:testRoomId success:^{ } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } diff --git a/MatrixSDKTests/MXStoreTests.m b/MatrixSDKTests/MXStoreTests.m index 29d35bdc0b..1a1de6f536 100644 --- a/MatrixSDKTests/MXStoreTests.m +++ b/MatrixSDKTests/MXStoreTests.m @@ -79,11 +79,13 @@ - (void)doTestWithStore:(id)store readyToTest(room); } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -117,10 +119,12 @@ - (void)doTestWithTwoUsersAndStore:(id)store readyToTest(room); } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; @@ -155,14 +159,15 @@ - (void)doTestWithStore:(id)store readyToTest(room); } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; - }]; } @@ -691,23 +696,28 @@ - (void)checkPaginateWhenJoiningAgainAfterLeft:(MXRoom*)room [aliceRestClient inviteUser:mxSession.matrixRestClient.credentials.userId toRoom:roomId success:^{ } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions"); + XCTFail(@"Cannot set up intial test conditions"); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions"); + XCTFail(@"Cannot set up intial test conditions"); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions"); + XCTFail(@"Cannot set up intial test conditions"); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions"); + XCTFail(@"Cannot set up intial test conditions"); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions"); + XCTFail(@"Cannot set up intial test conditions"); + [expectation fulfill]; }]; }]; } @@ -752,12 +762,12 @@ - (void)checkPaginateWhenReachingTheExactBeginningOfTheRoom:(MXRoom*)room }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); [expectation fulfill]; }]; } @@ -787,7 +797,7 @@ - (void)checkRedactEvent:(MXRoom*)room [room redactEvent:messageEventId reason:@"No reason" success:^{ } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); [expectation fulfill]; }]; } @@ -811,7 +821,7 @@ - (void)checkRedactEvent:(MXRoom*)room messageEventId = eventId; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); [expectation fulfill]; }]; } @@ -864,18 +874,22 @@ - (void)checkUserDisplaynameAndAvatarUrl:(Class)mxStoreClass [expectation fulfill]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -951,15 +965,18 @@ - (void)checkMXSessionOnStoreDataReady:(Class)mxStoreClass }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { @@ -968,10 +985,12 @@ - (void)checkMXSessionOnStoreDataReady:(Class)mxStoreClass }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; @@ -1013,19 +1032,23 @@ - (void)checkRoomDeletion:(Class)mxStoreClass [expectation fulfill]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -1071,15 +1094,18 @@ - (void)checkEventAge:(Class)mxStoreClass [expectation fulfill]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -1123,19 +1149,24 @@ - (void)checkMXRoomPaginationToken:(Class)mxStoreClass [expectation fulfill]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -1174,19 +1205,24 @@ - (void)checkMultiAccount:(Class)mxStoreClass [expectation fulfill]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -1252,11 +1288,13 @@ - (void)checkRoomAccountDataTags:(Class)mxStoreClass [expectation fulfill]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { @@ -1265,25 +1303,32 @@ - (void)checkRoomAccountDataTags:(Class)mxStoreClass }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } diff --git a/MatrixSDKTests/MXUserTests.m b/MatrixSDKTests/MXUserTests.m index 07798aa98b..9e9e486f6a 100644 --- a/MatrixSDKTests/MXUserTests.m +++ b/MatrixSDKTests/MXUserTests.m @@ -65,15 +65,18 @@ - (void)doTestWithBobAndAliceActiveInARoom:(void (^)(MXRestClient *bobRestClient readyToTest(bobRestClient, aliceRestClient, roomId, expectation); } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -138,7 +141,8 @@ - (void)testOtherUserLastActiveUpdate [aliceRestClient setPresence:MXPresenceOnline andStatusMessage:@"" success:^{ } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -163,7 +167,8 @@ - (void)testOtherUserProfileUpdate [aliceRestClient setDisplayName:@"ALICE" success:^{ } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -192,7 +197,8 @@ - (void)testOtherUserPresenceUpdate [aliceRestClient setPresence:MXPresenceUnavailable andStatusMessage:@"in Wonderland" success:^{ } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -215,7 +221,8 @@ - (void)testMyUserAvailability [expectation fulfill]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -235,7 +242,8 @@ - (void)testMyUserLastActiveUpdate [bobRestClient sendTextMessageToRoom:roomId text:@"A message to update my last active ago" success:^(NSString *eventId) { } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -265,11 +273,13 @@ - (void)testMyUserProfileUpdate [aliceRestClient setDisplayName:@"ALICE" success:^{ } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } @@ -305,11 +315,13 @@ - (void)testMyUserPresenceUpdate [aliceRestClient setPresence:MXPresenceUnavailable andStatusMessage:@"in Wonderland" success:^{ } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; diff --git a/MatrixSDKTests/MXVoIPTests.m b/MatrixSDKTests/MXVoIPTests.m index b6fb31c432..c7fb330b8f 100644 --- a/MatrixSDKTests/MXVoIPTests.m +++ b/MatrixSDKTests/MXVoIPTests.m @@ -104,7 +104,8 @@ - (void)testNoVoIPStackOnCallInvite }]; [aliceRestClient sendEventToRoom:roomId eventType:kMXEventTypeStringCallInvite content:content success:nil failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; }]; }]; } From 4c80ac99c9b278d68cdbdcf9f7df5cd6d1664835 Mon Sep 17 00:00:00 2001 From: manuroe Date: Wed, 18 May 2016 15:21:38 +0200 Subject: [PATCH 06/19] MXUserTests: Fixed test --- MatrixSDKTests/MXUserTests.m | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/MatrixSDKTests/MXUserTests.m b/MatrixSDKTests/MXUserTests.m index 9e9e486f6a..087b3ae6c8 100644 --- a/MatrixSDKTests/MXUserTests.m +++ b/MatrixSDKTests/MXUserTests.m @@ -155,12 +155,15 @@ - (void)testOtherUserProfileUpdate [mxAlice listenToUserUpdate:^(MXEvent *event) { - XCTAssertEqual(event.eventType, MXEventTypePresence); + XCTAssert(event.eventType == MXEventTypePresence || event.eventType == MXEventTypeRoomMember, @"%@", event); - XCTAssert([mxAlice.displayname isEqualToString:@"ALICE"]); - XCTAssert([mxAlice.avatarUrl isEqualToString:kMXTestsAliceAvatarURL]); + if (event.eventType == MXEventTypePresence) + { + XCTAssert([mxAlice.displayname isEqualToString:@"ALICE"]); + XCTAssert([mxAlice.avatarUrl isEqualToString:kMXTestsAliceAvatarURL]); - [expectation fulfill]; + [expectation fulfill]; + } }]; @@ -261,7 +264,7 @@ - (void)testMyUserProfileUpdate [mxSession.myUser listenToUserUpdate:^(MXEvent *event) { - XCTAssertEqual(event.eventType, MXEventTypePresence); + XCTAssert(event.eventType == MXEventTypePresence || event.eventType == MXEventTypeRoomMember, @"%@", event); XCTAssertEqualObjects(mxSession.myUser.displayname, @"ALICE"); XCTAssertEqualObjects(mxSession.myUser.avatarUrl, kMXTestsAliceAvatarURL); From 33ada19f9b31c62d73174367a43242ce51b79c2f Mon Sep 17 00:00:00 2001 From: manuroe Date: Wed, 18 May 2016 15:23:33 +0200 Subject: [PATCH 07/19] BF: Fixed implementation of userAccountData in MXMemoryStore and MXNoStore --- MatrixSDK/Data/Store/MXMemoryStore/MXMemoryStore.m | 2 +- MatrixSDK/Data/Store/MXNoStore/MXNoStore.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryStore.m b/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryStore.m index 7c952477ab..2da24bac45 100644 --- a/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryStore.m +++ b/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryStore.m @@ -27,7 +27,7 @@ @interface MXMemoryStore() @implementation MXMemoryStore -@synthesize eventStreamToken; +@synthesize eventStreamToken, userAccountData; - (instancetype)init { diff --git a/MatrixSDK/Data/Store/MXNoStore/MXNoStore.m b/MatrixSDK/Data/Store/MXNoStore/MXNoStore.m index beb86e65c6..51bb5596f6 100644 --- a/MatrixSDK/Data/Store/MXNoStore/MXNoStore.m +++ b/MatrixSDK/Data/Store/MXNoStore/MXNoStore.m @@ -41,7 +41,7 @@ @interface MXNoStore () @implementation MXNoStore -@synthesize eventStreamToken; +@synthesize eventStreamToken, userAccountData; - (instancetype)init { From f753609778d9a448400f43d098ce6ba65f0f9628 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 19 May 2016 10:04:41 +0200 Subject: [PATCH 08/19] Update README.rst: Fixed link to the Matrix iOS Console sample Added the use of MXFileStore use case --- README.rst | 67 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 15 deletions(-) diff --git a/README.rst b/README.rst index df907614b0..00f650e211 100644 --- a/README.rst +++ b/README.rst @@ -38,17 +38,17 @@ Matrix API level ---------------- :``MXRestClient``: Exposes the Matrix Client-Server API as specified by the Matrix standard to - make requests to a Home Server. + make requests to a homeserver. Business logic and data model ----------------------------- -These classes are higher level tools to handle responses from a Home Server. +These classes are higher level tools to handle responses from a homeserver. They contain logic to maintain consistent chat room data. :``MXSession``: - This class handles all data arriving from the Home Server. It uses a - MXRestClient instance to fetch data from the home server, forwarding it to + This class handles all data arriving from the homeserver. It uses a + MXRestClient instance to fetch data from the homeserver, forwarding it to MXRoom, MXRoomState, MXRoomMember and MXUser objects. :``MXRoom``: @@ -70,7 +70,7 @@ They contain logic to maintain consistent chat room data. Usage ===== -The sample app (https://github.com/matrix-org/matrix-ios-sdk/tree/master/samples/matrixConsole) +The sample app (https://github.com/matrix-org/matrix-ios-console) demonstrates how to build a chat app on top of Matrix. You can refer to it, play with it, hack it to understand the full integration of the Matrix SDK. This section comes back to the basics with sample codes for basic use cases. @@ -79,7 +79,7 @@ One file to import:: #import -Use case #1: Get public rooms of an home server +Use case #1: Get public rooms of an homeserver ----------------------------------------------- This API does not require the user to be authenticated. So, MXRestClient instantiated with initWithHomeServer does the job:: @@ -112,7 +112,7 @@ out:: // Create a matrix session MXSession *mxSession = [[MXSession alloc] initWithMatrixRestClient:mxRestClient]; - // Launch mxSession: it will first make an initial sync with the home server + // Launch mxSession: it will first make an initial sync with the homeserver // Then it will listen to new coming events and update its data [mxSession start:^{ @@ -122,6 +122,43 @@ out:: } failure:^(NSError *error) { }]; + + +Use case #2 (bis): Get the rooms the user has interacted with (using a permanent MXStore) +----------------------------------------------------------------------------------------- +We use the same code as below but we add a MXFileStore that will be in charge of +storing user's data on the file system. This will avoid to do a full sync with the +homeserver each time the app is resumed. The app will be able to resume quickly. +Plus, it will be able to run in offline mode while syncing with the homeserver:: + + MXCredentials *credentials = [[MXCredentials alloc] initWithHomeServer:@"http://matrix.org" + userId:@"@your_user_id:matrix.org" + accessToken:@"your_access_tokem"]; + + // Create a matrix session + MXRestClient *mxRestClient = [[MXRestClient alloc] initWithCredentials:credentials]; + + // Create a matrix session + MXSession *mxSession = [[MXSession alloc] initWithMatrixRestClient:mxRestClient]; + + // Make the matrix session open the file store + // This will preload user's messages and other data + MXFileStore *store = [[MXFileStore alloc] init]; + [mxSession setStore:store success:^{ + + // Launch mxSession: it will sync with the homeserver from the last stored data + // Then it will listen to new coming events and update its data + [mxSession start:^{ + + // mxSession is ready to be used + // Now we can get all rooms with: + mxSession.rooms; + + } failure:^(NSError *error) { + }]; + } failure:^(NSError *error) { + }]; + Use case #3: Get messages of a room @@ -167,7 +204,7 @@ MXRestClient directly:: // event_id is for reference // If you have registered events listener like in the previous use case, you will get - // a notification for this event coming down from the home server events stream and + // a notification for this event coming down from the homeserver events stream and // now handled by MXSession. } failure:^(NSError *error) { @@ -177,7 +214,7 @@ MXRestClient directly:: Push Notifications ================== -In Matrix, a Home Server can send notifications out to a user when events +In Matrix, a homeserver can send notifications out to a user when events arrive for them. However in APNS, only you, the app developer, can send APNS notifications because doing so requires your APNS private key. Matrix therefore requires a seperate server decoupled from the homeserver to send @@ -248,7 +285,7 @@ encoding for APNS tokens (as this is what sygnal uses):: ]; } -When you call setPusherWithPushkey, this creates a pusher on the Home Server +When you call setPusherWithPushkey, this creates a pusher on the homeserver that your session is logged in to. This will send HTTP notifications to a URL you supply as the 'url' key in the 'data' argument to setPusherWithPushkey. @@ -258,7 +295,7 @@ little more information about some of these parameters is included below: appId This has two purposes: firstly to form the namespace in which your pushkeys - exist on a Home Server, which means you should use something unique to your + exist on a homeserver, which means you should use something unique to your application: a reverse-DNS style identifier is strongly recommended. Its second purpose is to identify your application to your Push Gateway, such that your Push Gateway knows which private key and certificate to use when talking @@ -298,7 +335,7 @@ Tests ===== The tests in the SDK Xcode project are both unit and integration tests. -Out of the box, the tests use one of the home servers (located at +Out of the box, the tests use one of the homeservers (located at http://localhost:8080) of the "Demo Federation of Homeservers" (https://github.com/matrix-org/synapse#running-a-demo-federation-of-homeservers) . You have to start them from your local Synapse folder:: @@ -321,12 +358,12 @@ the cocoapods team. Registration ------------ The SDK currently manages only login-password type registration. -This type of registration is not accepted by the home server hosted at +This type of registration is not accepted by the homeserver hosted at matrix.org. It has been disabled for security and spamming reasons. So, for now, you will be not be able to register a new account with the SDK on -such home server. But you can login an existing user. +such homeserver. But you can login an existing user. -If you run your own home server, the default launch parameters enables the +If you run your own homeserver, the default launch parameters enables the login-password type registration and you will be able to register a new user to it. From d0aec67db73255cd86f054b56500996b361425c8 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 19 May 2016 16:25:25 +0200 Subject: [PATCH 09/19] Push rules update: Listen to account_data to get push rules updates. This avoids to make a /pushrules get request everytime the app starts or resumes. --- MatrixSDK.xcodeproj/project.pbxproj | 12 + MatrixSDK/Data/MXAccountData.h | 41 ++++ MatrixSDK/Data/MXAccountData.m | 59 +++++ MatrixSDK/JSONModels/MXJSONModels.m | 13 + MatrixSDK/MXRestClient.h | 1 + MatrixSDK/MXRestClient.m | 1 + MatrixSDK/MXSession.m | 225 ++++++++---------- .../NotificationCenter/MXNotificationCenter.h | 8 + .../NotificationCenter/MXNotificationCenter.m | 39 +-- MatrixSDKTests/MXAccountDataTests.m | 199 ++++++++++++++++ 10 files changed, 460 insertions(+), 138 deletions(-) create mode 100644 MatrixSDK/Data/MXAccountData.h create mode 100644 MatrixSDK/Data/MXAccountData.m create mode 100644 MatrixSDKTests/MXAccountDataTests.m diff --git a/MatrixSDK.xcodeproj/project.pbxproj b/MatrixSDK.xcodeproj/project.pbxproj index a0b5299e6f..1159b8f635 100644 --- a/MatrixSDK.xcodeproj/project.pbxproj +++ b/MatrixSDK.xcodeproj/project.pbxproj @@ -65,6 +65,9 @@ 325653831A2E14ED00CC0423 /* MXStoreTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 325653821A2E14ED00CC0423 /* MXStoreTests.m */; }; 326056851C76FDF2009D44AD /* MXEventTimeline.h in Headers */ = {isa = PBXBuildFile; fileRef = 326056831C76FDF1009D44AD /* MXEventTimeline.h */; }; 326056861C76FDF2009D44AD /* MXEventTimeline.m in Sources */ = {isa = PBXBuildFile; fileRef = 326056841C76FDF1009D44AD /* MXEventTimeline.m */; }; + 3264DB911CEC528D00B99881 /* MXAccountData.h in Headers */ = {isa = PBXBuildFile; fileRef = 3264DB8F1CEC528D00B99881 /* MXAccountData.h */; }; + 3264DB921CEC528D00B99881 /* MXAccountData.m in Sources */ = {isa = PBXBuildFile; fileRef = 3264DB901CEC528D00B99881 /* MXAccountData.m */; }; + 3264DB941CECA72900B99881 /* MXAccountDataTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3264DB931CECA72900B99881 /* MXAccountDataTests.m */; }; 3264E2A21BDF8D1500F89A86 /* MXCoreDataRoomState.h in Headers */ = {isa = PBXBuildFile; fileRef = 3264E29E1BDF8D1500F89A86 /* MXCoreDataRoomState.h */; }; 3264E2A31BDF8D1500F89A86 /* MXCoreDataRoomState.m in Sources */ = {isa = PBXBuildFile; fileRef = 3264E29F1BDF8D1500F89A86 /* MXCoreDataRoomState.m */; }; 3264E2A41BDF8D1500F89A86 /* MXCoreDataRoomState+CoreDataProperties.h in Headers */ = {isa = PBXBuildFile; fileRef = 3264E2A01BDF8D1500F89A86 /* MXCoreDataRoomState+CoreDataProperties.h */; }; @@ -213,6 +216,9 @@ 325653821A2E14ED00CC0423 /* MXStoreTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXStoreTests.m; sourceTree = ""; }; 326056831C76FDF1009D44AD /* MXEventTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MXEventTimeline.h; sourceTree = ""; }; 326056841C76FDF1009D44AD /* MXEventTimeline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXEventTimeline.m; sourceTree = ""; }; + 3264DB8F1CEC528D00B99881 /* MXAccountData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MXAccountData.h; sourceTree = ""; }; + 3264DB901CEC528D00B99881 /* MXAccountData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXAccountData.m; sourceTree = ""; }; + 3264DB931CECA72900B99881 /* MXAccountDataTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXAccountDataTests.m; sourceTree = ""; }; 3264E29E1BDF8D1500F89A86 /* MXCoreDataRoomState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MXCoreDataRoomState.h; sourceTree = ""; }; 3264E29F1BDF8D1500F89A86 /* MXCoreDataRoomState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXCoreDataRoomState.m; sourceTree = ""; }; 3264E2A01BDF8D1500F89A86 /* MXCoreDataRoomState+CoreDataProperties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MXCoreDataRoomState+CoreDataProperties.h"; sourceTree = ""; }; @@ -339,6 +345,8 @@ 329FB1741A0A3A1600A5E88E /* MXRoomMember.m */, 327F8DB01C6112BA00581CA3 /* MXRoomThirdPartyInvite.h */, 327F8DB11C6112BA00581CA3 /* MXRoomThirdPartyInvite.m */, + 3264DB8F1CEC528D00B99881 /* MXAccountData.h */, + 3264DB901CEC528D00B99881 /* MXAccountData.m */, 329FB17D1A0B665800A5E88E /* MXUser.h */, 329FB17E1A0B665800A5E88E /* MXUser.m */, 327137251A24D50A00DB6757 /* MXMyUser.h */, @@ -551,6 +559,7 @@ 323C5A071A70E53500FB0549 /* MXToolsTests.m */, 32DC15D61A8DFF0D006F9AD3 /* MXNotificationCenterTests.m */, 329571921B0240CE00ABB3BA /* MXVoIPTests.m */, + 3264DB931CECA72900B99881 /* MXAccountDataTests.m */, ); path = MatrixSDKTests; sourceTree = ""; @@ -647,6 +656,7 @@ 323B2AE11BCD4CB600B11F34 /* MXCoreDataAccount.h in Headers */, 3220094519EFBF30008DE41D /* MXSessionEventListener.h in Headers */, 32BED28F1B00A23F00E668FE /* MXCallStack.h in Headers */, + 3264DB911CEC528D00B99881 /* MXAccountData.h in Headers */, 323B2AF81BCE8AC800B11F34 /* MXCoreDataRoom.h in Headers */, 329FB1751A0A3A1600A5E88E /* MXRoomMember.h in Headers */, 323B2ACF1BCD3EF000B11F34 /* MXCoreDataStore.h in Headers */, @@ -823,6 +833,7 @@ 327137281A24D50A00DB6757 /* MXMyUser.m in Sources */, 32114A901A262ECB00FF2EC4 /* MXNoStore.m in Sources */, 32CE6FB91A409B1F00317F1E /* MXFileStoreMetaData.m in Sources */, + 3264DB921CEC528D00B99881 /* MXAccountData.m in Sources */, 323E0C5C1A306D7A00A31D73 /* MXEvent.m in Sources */, 323B2AFF1BCE9B6700B11F34 /* MXCoreDataEvent+CoreDataProperties.m in Sources */, 32CAB10C1A925B41008C5BB9 /* MXHTTPOperation.m in Sources */, @@ -877,6 +888,7 @@ 32FCAB4D19E578860049C555 /* MXRestClientTests.m in Sources */, 329FB17C1A0A963700A5E88E /* MXRoomMemberTests.m in Sources */, 3246BDC51A1A0789000A7D62 /* MXRoomStateDynamicTests.m in Sources */, + 3264DB941CECA72900B99881 /* MXAccountDataTests.m in Sources */, 323EF7471C7CB4C7000DC98C /* MXEventTimelineTests.m in Sources */, 32169AA21BD4D1B00077868B /* MXCoreDataStore.xcdatamodeld in Sources */, ); diff --git a/MatrixSDK/Data/MXAccountData.h b/MatrixSDK/Data/MXAccountData.h new file mode 100644 index 0000000000..7806bae26c --- /dev/null +++ b/MatrixSDK/Data/MXAccountData.h @@ -0,0 +1,41 @@ +/* + Copyright 2016 OpenMarket Ltd + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +#import + +/** + `MXAccountData` holds the user account data. + + Account data contains infomation like the push rules and the ignored users list. + It is fully or partially updated on homeserver `/sync` response. + + The main purpose of this class is to maintain the data with partial update. + */ +@interface MXAccountData : NSObject + +/** + Update the account data with the passed event. + + @param event one event of the "account_data" field of a `/sync` response. + */ +- (void)updateWithEvent:(NSDictionary*)event; + +/** + The account data as sent by the homeserver /sync response. + */ +@property (nonatomic, readonly) NSDictionary *accountData; + +@end diff --git a/MatrixSDK/Data/MXAccountData.m b/MatrixSDK/Data/MXAccountData.m new file mode 100644 index 0000000000..300d71fdcd --- /dev/null +++ b/MatrixSDK/Data/MXAccountData.m @@ -0,0 +1,59 @@ +/* + Copyright 2016 OpenMarket Ltd + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +#import "MXAccountData.h" + +@interface MXAccountData () +{ + /** + This dictionary stores "account_data" data in a flat manner. + */ + NSMutableDictionary *accountDataDict; +} +@end + +@implementation MXAccountData + +- (instancetype)init +{ + self = [super init]; + if (self) + { + accountDataDict = [NSMutableDictionary dictionary]; + } + return self; +} + +- (void)updateWithEvent:(NSDictionary *)event +{ + accountDataDict[event[@"type"]] = event[@"content"]; +} + +- (NSDictionary *)accountData +{ + // Rebuild the dictionary as sent by the homeserver + NSMutableArray *events = [NSMutableArray array]; + for (NSString *type in accountDataDict) + { + [events addObject:@{ + @"type": type, + @"content": accountDataDict[type] + }]; + } + return @{@"events": events}; +} + +@end diff --git a/MatrixSDK/JSONModels/MXJSONModels.m b/MatrixSDK/JSONModels/MXJSONModels.m index 876ade679a..b261178e8c 100644 --- a/MatrixSDK/JSONModels/MXJSONModels.m +++ b/MatrixSDK/JSONModels/MXJSONModels.m @@ -606,6 +606,12 @@ + (id)modelFromJSON:(NSDictionary *)JSONDictionary withScope:(NSString*)scope @end +@interface MXPushRulesResponse () +{ + // The dictionary sent by the homeserver. + NSDictionary *JSONDictionary; +} +@end @implementation MXPushRulesResponse NSString *const kMXPushRuleScopeStringGlobal = @"global"; @@ -622,11 +628,18 @@ + (id)modelFromJSON:(NSDictionary *)JSONDictionary } // TODO support device rules + + pushRulesResponse->JSONDictionary = JSONDictionary; } return pushRulesResponse; } +- (NSDictionary *)JSONDictionary +{ + return JSONDictionary; +} + @end diff --git a/MatrixSDK/MXRestClient.h b/MatrixSDK/MXRestClient.h index f030339274..9e813b3ee7 100644 --- a/MatrixSDK/MXRestClient.h +++ b/MatrixSDK/MXRestClient.h @@ -58,6 +58,7 @@ FOUNDATION_EXPORT NSString *const kMXRoomVisibilityPrivate; /** Account data types */ +FOUNDATION_EXPORT NSString *const kMXAccountDataPushRules; FOUNDATION_EXPORT NSString *const kMXAccountDataTypeIgnoredUserList; /** diff --git a/MatrixSDK/MXRestClient.m b/MatrixSDK/MXRestClient.m index 35f76cc626..a62798e45d 100644 --- a/MatrixSDK/MXRestClient.m +++ b/MatrixSDK/MXRestClient.m @@ -48,6 +48,7 @@ Account data types */ NSString *const kMXAccountDataTypeIgnoredUserList = @"m.ignored_user_list"; +NSString *const kMXAccountDataPushRules = @"m.push_rules"; /** Account data keys diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index 40727f153f..cf3e79980e 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -26,6 +26,8 @@ #import "MXMemoryStore.h" #import "MXFileStore.h" +#import "MXAccountData.h" + #pragma mark - Constants definitions const NSString *MatrixSDKVersion = @"0.6.7"; @@ -105,6 +107,11 @@ The list of global events listeners (`MXSessionEventListener`). The maintained list of rooms where the user has a pending invitation. */ NSMutableArray *invitedRooms; + + /** + The account data. + */ + MXAccountData *accountData; } @end @@ -123,6 +130,7 @@ - (id)initWithMatrixRestClient:(MXRestClient*)mxRestClient globalEventListeners = [NSMutableArray array]; syncMessagesLimit = -1; _notificationCenter = [[MXNotificationCenter alloc] initWithMatrixSession:self]; + accountData = [[MXAccountData alloc] init]; [self setState:MXSessionStateInitialised]; } @@ -173,54 +181,37 @@ -(void)setStore:(id)store success:(void (^)())onStoreDataReady failure: // Can we start on data from the MXStore? if (_store.isPermanent && _store.eventStreamToken && 0 < _store.rooms.count) { - // Define here a method to load data from store - void (^loadStoreData) () = ^void() { - // Mount data from the permanent store - NSLog(@"[MXSession] Loading room state events to build MXRoom objects..."); - - // Create the user's profile from the store - _myUser = [[MXMyUser alloc] initWithUserId:matrixRestClient.credentials.userId andDisplayname:_store.userDisplayname andAvatarUrl:_store.userAvatarUrl andMatrixSession:self]; - // And store him as a common MXUser - users[matrixRestClient.credentials.userId] = _myUser; + // Mount data from the permanent store + NSLog(@"[MXSession] Loading room state events to build MXRoom objects..."); - // Load user account data - _ignoredUsers = [self ignoredUsersFromAccountData:_store.userAccountData]; + // Create the user's profile from the store + _myUser = [[MXMyUser alloc] initWithUserId:matrixRestClient.credentials.userId andDisplayname:_store.userDisplayname andAvatarUrl:_store.userAvatarUrl andMatrixSession:self]; + // And store him as a common MXUser + users[matrixRestClient.credentials.userId] = _myUser; - // Create MXRooms from their states stored in the store - NSDate *startDate2 = [NSDate date]; - for (NSString *roomId in _store.rooms) + // Load user account data + [self handleAccountData:_store.userAccountData]; + + // Create MXRooms from their states stored in the store + NSDate *startDate2 = [NSDate date]; + for (NSString *roomId in _store.rooms) + { + @autoreleasepool { - @autoreleasepool - { - NSArray *stateEvents = [_store stateOfRoom:roomId]; - MXRoomAccountData *roomAccountData = [_store accountDataOfRoom:roomId]; - [self createRoom:roomId withStateEvents:stateEvents andAccountData:roomAccountData notify:NO]; - } + NSArray *stateEvents = [_store stateOfRoom:roomId]; + MXRoomAccountData *roomAccountData = [_store accountDataOfRoom:roomId]; + [self createRoom:roomId withStateEvents:stateEvents andAccountData:roomAccountData notify:NO]; } - - NSLog(@"[MXSession] Built %lu MXRooms in %.0fms", (unsigned long)rooms.allKeys.count, [[NSDate date] timeIntervalSinceDate:startDate2] * 1000); - - NSLog(@"[MXSession] Total time to mount SDK data from MXStore: %.0fms", [[NSDate date] timeIntervalSinceDate:startDate] * 1000); - - [self setState:MXSessionStateStoreDataReady]; - - // The SDK client can use this data - onStoreDataReady(); - }; - - // Reload first the push rules to display correctly bing events. - // The store data are loaded even if this operation failed to let the app run in offline mode. - NSLog(@"[MXSession] Reload push rules from the home server..."); - MXHTTPOperation *operation = [_notificationCenter refreshRules:^{ - loadStoreData(); - } failure:^(NSError *error) { - loadStoreData(); - }]; + } + + NSLog(@"[MXSession] Built %lu MXRooms in %.0fms", (unsigned long)rooms.allKeys.count, [[NSDate date] timeIntervalSinceDate:startDate2] * 1000); - // Attempt to retrieve them only once: if there is no network, - // we do not want to be blocked by the MXHTTPClient that will wait - // for the network to be back before retry internally. - operation.maxNumberOfTries = 1; + NSLog(@"[MXSession] Total time to mount SDK data from MXStore: %.0fms", [[NSDate date] timeIntervalSinceDate:startDate] * 1000); + + [self setState:MXSessionStateStoreDataReady]; + + // The SDK client can use this data + onStoreDataReady(); } else { @@ -305,24 +296,15 @@ - (void)startWithMessagesLimit:(NSUInteger)messagesLimit // And store him as a common MXUser users[matrixRestClient.credentials.userId] = _myUser; - - // Additional step: load push rules from the home server - [_notificationCenter refreshRules:^{ - - // Initial server sync - [self serverSyncWithServerTimeout:0 success:onServerSyncDone failure:^(NSError *error) { - - [self setState:MXSessionStateInitialSyncFailed]; - failure(error); - - } clientTimeout:CLIENT_TIMEOUT_MS setPresence:nil]; - - } failure:^(NSError *error) { + // Initial server sync + [self serverSyncWithServerTimeout:0 success:onServerSyncDone failure:^(NSError *error) { + [self setState:MXSessionStateInitialSyncFailed]; failure(error); - - }]; + + } clientTimeout:CLIENT_TIMEOUT_MS setPresence:nil]; + } failure:^(NSError *error) { [self setState:MXSessionStateInitialSyncFailed]; @@ -338,19 +320,6 @@ - (void)startWithMessagesLimit:(NSUInteger)messagesLimit } } -- (void)handlePresenceEvent:(MXEvent *)event direction:(MXTimelineDirection)direction -{ - // Update MXUser with presence data - NSString *userId = event.sender; - if (userId) - { - MXUser *user = [self getOrCreateUser:userId]; - [user updateWithPresenceEvent:event]; - } - - [self notifyListeners:event direction:direction]; -} - - (void)pause { NSLog(@"[MXSession] pause the event stream in state %tu", _state); @@ -375,11 +344,6 @@ - (void)resume:(void (^)())resumeDone // Check whether no request is already in progress if (!eventStreamRequest || (_state == MXSessionStateBackgroundSyncInProgress)) { - // Force reload of push rules now. - // The spec, @see SPEC-106 ticket, does not allow to be notified when there was a change - // of push rules server side. Reload them when resuming the SDK is a good time - [_notificationCenter refreshRules:nil failure:nil]; - [self setState:MXSessionStateSyncInProgress]; // Resume from the last known token @@ -631,30 +595,7 @@ - (void)serverSyncWithServerTimeout:(NSUInteger)serverTimeout // Handle top-level account data if (syncResponse.accountData) { - // Well, manage only the ignored users list for now - NSArray *newIgnoredUsers = [self ignoredUsersFromAccountData:syncResponse.accountData]; - if (newIgnoredUsers) - { - // Check the array changes whatever the order - NSCountedSet *set1 = [NSCountedSet setWithArray:_ignoredUsers]; - NSCountedSet *set2 = [NSCountedSet setWithArray:newIgnoredUsers]; - - // Do not notify for the first /sync - BOOL notify = !isInitialSync && ![set1 isEqualToSet:set2]; - - _ignoredUsers = newIgnoredUsers; - - // Report the change - if (notify) - { - [[NSNotificationCenter defaultCenter] postNotificationName:kMXSessionIgnoredUsersDidChangeNotification - object:self - userInfo:nil]; - } - } - - // Store it - _store.userAccountData = syncResponse.accountData; + [self handleAccountData:syncResponse.accountData]; } // Update live event stream token @@ -841,6 +782,69 @@ - (void)serverSyncWithServerTimeout:(NSUInteger)serverTimeout }]; } +- (void)handlePresenceEvent:(MXEvent *)event direction:(MXTimelineDirection)direction +{ + // Update MXUser with presence data + NSString *userId = event.sender; + if (userId) + { + MXUser *user = [self getOrCreateUser:userId]; + [user updateWithPresenceEvent:event]; + } + + [self notifyListeners:event direction:direction]; +} + +- (void)handleAccountData:(NSDictionary*)accountDataUpdate +{ + if (accountDataUpdate && accountDataUpdate[@"events"]) + { + for (NSDictionary *event in accountDataUpdate[@"events"]) + { + if ([event[@"type"] isEqualToString:kMXAccountDataPushRules]) + { + // Handle push rules + MXPushRulesResponse *pushRules = [MXPushRulesResponse modelFromJSON:event[@"content"]]; + + if (![_notificationCenter.rules.JSONDictionary isEqualToDictionary:event[@"content"]]) + { + [_notificationCenter handlePushRulesResponse:pushRules]; + } + } + else if ([event[@"type"] isEqualToString:kMXAccountDataTypeIgnoredUserList]) + { + // Handle the ignored users list + NSArray *newIgnoredUsers = [event[@"content"][kMXAccountDataKeyIgnoredUser] allKeys]; + if (newIgnoredUsers) + { + // Check the array changes whatever the order + NSCountedSet *set1 = [NSCountedSet setWithArray:_ignoredUsers]; + NSCountedSet *set2 = [NSCountedSet setWithArray:newIgnoredUsers]; + + // Do not notify for the first /sync + BOOL isInitialSync = !_store.eventStreamToken; + BOOL notify = !isInitialSync && ![set1 isEqualToSet:set2]; + + _ignoredUsers = newIgnoredUsers; + + // Report the change + if (notify) + { + [[NSNotificationCenter defaultCenter] postNotificationName:kMXSessionIgnoredUsersDidChangeNotification + object:self + userInfo:nil]; + } + } + } + + // Update the corresponding part of account data + [accountData updateWithEvent:event]; + } + + _store.userAccountData = accountData.accountData; + } +} + #pragma mark - Options - (void)enableVoIPWithCallStack:(id)callStack { @@ -1351,27 +1355,6 @@ - (MXHTTPOperation *)unIgnoreUsers:(NSArray *)userIds success:(void } failure:failure]; } -/** - Extract the ignored users list from the account data dictionary. - - @param accountData the account data dictionary. - @return the ignored users list. nil if there is nothing. - */ -- (NSArray*)ignoredUsersFromAccountData:(NSDictionary*)accountData -{ - NSArray *ignoredUsers; - - for (NSDictionary *event in accountData[@"events"]) - { - if ([event[@"type"] isEqualToString:kMXAccountDataTypeIgnoredUserList]) - { - ignoredUsers = [event[@"content"][kMXAccountDataKeyIgnoredUser] allKeys]; - } - } - - return ignoredUsers; -} - #pragma mark - User's recents - (NSArray*)recentsWithTypeIn:(NSArray*)types diff --git a/MatrixSDK/NotificationCenter/MXNotificationCenter.h b/MatrixSDK/NotificationCenter/MXNotificationCenter.h index c27003ae9c..e4b2985ff8 100644 --- a/MatrixSDK/NotificationCenter/MXNotificationCenter.h +++ b/MatrixSDK/NotificationCenter/MXNotificationCenter.h @@ -125,6 +125,14 @@ extern NSString *const kMXNotificationCenterAllOtherRoomMessagesRuleID; - (MXHTTPOperation *)refreshRules:(void (^)())success failure:(void (^)(NSError *error))failure; + +/** + Handle an update of the push rules. + + @param pushRules the new push rules. + */ +- (void)handlePushRulesResponse:(MXPushRulesResponse*)pushRules; + /** Set a push rule condition checker for a kind of condition. This method allows the SDK client to handle custom types of condtions. diff --git a/MatrixSDK/NotificationCenter/MXNotificationCenter.m b/MatrixSDK/NotificationCenter/MXNotificationCenter.m index 49bd596b39..803af81fad 100644 --- a/MatrixSDK/NotificationCenter/MXNotificationCenter.m +++ b/MatrixSDK/NotificationCenter/MXNotificationCenter.m @@ -104,23 +104,7 @@ - (MXHTTPOperation *)refreshRules:(void (^)())success failure:(void (^)(NSError { return [mxSession.matrixRestClient pushRules:^(MXPushRulesResponse *pushRules) { - _rules = pushRules; - - @synchronized(self) - { - flatRules = [NSMutableArray array]; - - // Add rules by their priority - - // @TODO: manage device rules - - // Global rules - [flatRules addObjectsFromArray:pushRules.global.override]; - [flatRules addObjectsFromArray:pushRules.global.content]; - [flatRules addObjectsFromArray:pushRules.global.room]; - [flatRules addObjectsFromArray:pushRules.global.sender]; - [flatRules addObjectsFromArray:pushRules.global.underride]; - } + [self handlePushRulesResponse:pushRules]; if (success) { @@ -137,6 +121,27 @@ - (MXHTTPOperation *)refreshRules:(void (^)())success failure:(void (^)(NSError }]; } +- (void)handlePushRulesResponse:(MXPushRulesResponse*)pushRules +{ + _rules = pushRules; + + @synchronized(self) + { + flatRules = [NSMutableArray array]; + + // Add rules by their priority + + // @TODO: manage device rules + + // Global rules + [flatRules addObjectsFromArray:pushRules.global.override]; + [flatRules addObjectsFromArray:pushRules.global.content]; + [flatRules addObjectsFromArray:pushRules.global.room]; + [flatRules addObjectsFromArray:pushRules.global.sender]; + [flatRules addObjectsFromArray:pushRules.global.underride]; + } +} + - (void)setChecker:(id)checker forConditionKind:(MXPushRuleConditionString)conditionKind { [conditionCheckers setObject:checker forKey:conditionKind]; diff --git a/MatrixSDKTests/MXAccountDataTests.m b/MatrixSDKTests/MXAccountDataTests.m new file mode 100644 index 0000000000..d01f853325 --- /dev/null +++ b/MatrixSDKTests/MXAccountDataTests.m @@ -0,0 +1,199 @@ +/* + Copyright 2016 OpenMarket Ltd + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +#import +#import + +#import "MatrixSDKTestsData.h" + +#import "MXSession.h" +#import "MXFileStore.h" + +// Do not bother with retain cycles warnings in tests +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-retain-cycles" + +@interface MXAccountDataTests : XCTestCase +{ + MatrixSDKTestsData *matrixSDKTestsData; +} +@end + +@implementation MXAccountDataTests + +- (void)setUp +{ + [super setUp]; + + matrixSDKTestsData = [[MatrixSDKTestsData alloc] init]; +} + +- (void)tearDown +{ + [super tearDown]; +} + +- (void)testIgnoreUser +{ + [matrixSDKTestsData doMXSessionTestWithBobAndAliceInARoom:self readyToTest:^(MXSession *bobSession, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { + + XCTAssertEqual(bobSession.ignoredUsers.count, 0); + XCTAssertEqual([bobSession isUserIgnored:aliceRestClient.credentials.userId], NO); + + // Listen to bobSession.ignoredUsers changes + [[NSNotificationCenter defaultCenter] addObserverForName:kMXSessionIgnoredUsersDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull notif) { + + if (notif.object == bobSession) + { + XCTAssertEqual(bobSession.ignoredUsers.count, 1); + XCTAssertEqual([bobSession isUserIgnored:aliceRestClient.credentials.userId], YES); + + [expectation fulfill]; + } + }]; + + // Ignore Alice + [bobSession ignoreUsers:@[aliceRestClient.credentials.userId] success:nil failure:^(NSError *error) { + XCTFail(@"The request should not fail - NSError: %@", error); + [expectation fulfill]; + }]; + + }]; +} + +// Make sure the ignoredUsers list is still here after resuming a Matrix app +- (void)testIgnoreUsersStorage +{ + [matrixSDKTestsData doMXRestClientTestWithBobAndAliceInARoom:self readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { + + MXSession *bobSession = [[MXSession alloc] initWithMatrixRestClient:bobRestClient]; + + MXFileStore *store = [[MXFileStore alloc] init]; + [bobSession setStore:store success:^{ + [bobSession start:^{ + + // Listen to bobSession.ignoredUsers changes + [[NSNotificationCenter defaultCenter] addObserverForName:kMXSessionIgnoredUsersDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull notif) { + + if (notif.object == bobSession) + { + // Yield so that bobSession completes the saving to the cache. + dispatch_async(dispatch_get_main_queue(), ^{ + + [bobSession close]; + + // Check the information have been permanently stored + MXSession *bobSession2 = [[MXSession alloc] initWithMatrixRestClient:bobRestClient]; + MXFileStore *store2 = [[MXFileStore alloc] init]; + [bobSession2 setStore:store2 success:^{ + + XCTAssertEqual(bobSession2.ignoredUsers.count, 1); + XCTAssertEqual([bobSession2 isUserIgnored:aliceRestClient.credentials.userId], YES); + + [expectation fulfill]; + + } failure:^(NSError *error) { + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; + }]; + }); + } + + }]; + + // Ignore Alice + [bobSession ignoreUsers:@[aliceRestClient.credentials.userId] success:nil failure:^(NSError *error) { + XCTFail(@"The request should not fail - NSError: %@", error); + [expectation fulfill]; + }]; + + } failure:^(NSError *error) { + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; + }]; + } failure:^(NSError *error) { + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; + }]; + + }]; +} + +// Make sure an update of ignoredUsers does not kill pushRules +// The reason to test it is that in case of ignoredUsers update, the HS sends only part of +// the account data concerning ignoredUsers +- (void)testIgnoreUserUpdateHasNoCollateralDamageOnPushRules +{ + [matrixSDKTestsData doMXRestClientTestWithBobAndAliceInARoom:self readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { + + MXSession *bobSession = [[MXSession alloc] initWithMatrixRestClient:bobRestClient]; + + MXFileStore *store = [[MXFileStore alloc] init]; + [bobSession setStore:store success:^{ + [bobSession start:^{ + + MXPushRulesResponse *pushRules = bobSession.notificationCenter.rules; + + // Listen to bobSession.ignoredUsers changes + [[NSNotificationCenter defaultCenter] addObserverForName:kMXSessionIgnoredUsersDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull notif) { + + if (notif.object == bobSession) + { + // Yield so that bobSession completes the saving to the cache. + dispatch_async(dispatch_get_main_queue(), ^{ + + [bobSession close]; + + // Check the information have been permanently stored + MXSession *bobSession2 = [[MXSession alloc] initWithMatrixRestClient:bobRestClient]; + MXFileStore *store2 = [[MXFileStore alloc] init]; + [bobSession2 setStore:store2 success:^{ + + MXPushRulesResponse *pushRules2 = bobSession2.notificationCenter.rules; + + XCTAssert([pushRules.JSONDictionary isEqualToDictionary:pushRules2.JSONDictionary], @"Push Rules has unexpectedly changed: \n%@\nto:\n%@", pushRules.JSONDictionary, pushRules2.JSONDictionary); + + [expectation fulfill]; + + } failure:^(NSError *error) { + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; + }]; + }); + } + }]; + + // Ignore Alice + [bobSession ignoreUsers:@[aliceRestClient.credentials.userId] success:nil failure:^(NSError *error) { + XCTFail(@"The request should not fail - NSError: %@", error); + [expectation fulfill]; + }]; + + } failure:^(NSError *error) { + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; + }]; + } failure:^(NSError *error) { + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; + }]; + }]; +} + + +@end + +#pragma clang diagnostic pop From f6a40db5400a2fa11f4e272b4efed4ca958f1186 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 19 May 2016 16:49:09 +0200 Subject: [PATCH 10/19] Push rules update: Post kMXNotificationCenterDidUpdateRules on pushrules update detection --- MatrixSDK/MXSession.m | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index cf3e79980e..69f0abe7a0 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -799,6 +799,8 @@ - (void)handleAccountData:(NSDictionary*)accountDataUpdate { if (accountDataUpdate && accountDataUpdate[@"events"]) { + BOOL isInitialSync = !_store.eventStreamToken; + for (NSDictionary *event in accountDataUpdate[@"events"]) { if ([event[@"type"] isEqualToString:kMXAccountDataPushRules]) @@ -809,6 +811,14 @@ - (void)handleAccountData:(NSDictionary*)accountDataUpdate if (![_notificationCenter.rules.JSONDictionary isEqualToDictionary:event[@"content"]]) { [_notificationCenter handlePushRulesResponse:pushRules]; + + // Report the change + if (!isInitialSync) + { + [[NSNotificationCenter defaultCenter] postNotificationName:kMXNotificationCenterDidUpdateRules + object:_notificationCenter + userInfo:nil]; + } } } else if ([event[@"type"] isEqualToString:kMXAccountDataTypeIgnoredUserList]) @@ -822,7 +832,6 @@ - (void)handleAccountData:(NSDictionary*)accountDataUpdate NSCountedSet *set2 = [NSCountedSet setWithArray:newIgnoredUsers]; // Do not notify for the first /sync - BOOL isInitialSync = !_store.eventStreamToken; BOOL notify = !isInitialSync && ![set1 isEqualToSet:set2]; _ignoredUsers = newIgnoredUsers; From 890074050cc4ae6f15faebeaf8825b26ec5e6667 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 19 May 2016 18:27:04 +0200 Subject: [PATCH 11/19] MXSession: Detect when the access token is no more valid (https://github.com/vector-im/vector-ios/issues/247). In this situation, the session is in a new state MXSessionStateUnknownToken. --- MatrixSDK/MXSession.h | 12 +++++++++++- MatrixSDK/MXSession.m | 14 ++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/MatrixSDK/MXSession.h b/MatrixSDK/MXSession.h index f3c3a43543..42cf82132f 100644 --- a/MatrixSDK/MXSession.h +++ b/MatrixSDK/MXSession.h @@ -85,7 +85,17 @@ typedef enum : NSUInteger @discussion The Matrix session will stay in this state until a new call of [MXSession start:failure:]. */ - MXSessionStateInitialSyncFailed + MXSessionStateInitialSyncFailed, + + /** + The access token is no more valid. + + @discussion + This can happen when the user made a forget password request for example. + The Matrix session is no more usable. The user must log in again. + */ + MXSessionStateUnknownToken + } MXSessionState; diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index 69f0abe7a0..4634e2d4f6 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -679,6 +679,20 @@ - (void)serverSyncWithServerTimeout:(NSUInteger)serverTimeout { return; } + + if ([MXError isMXError:error]) + { + // Detect invalidated access token + // This can happen when the user made a forget password request for example + MXError *mxError = [[MXError alloc] initWithNSError:error]; + if ([mxError.errcode isEqualToString:kMXErrCodeStringUnknownToken]) + { + [self setState:MXSessionStateUnknownToken]; + + // Do nothing more because without a valid access_token, the session is useless + return; + } + } // Handle failure during catch up first if (onBackgroundSyncFail) From cf9904e32933e6f20869cf195476740399c8a613 Mon Sep 17 00:00:00 2001 From: manuroe Date: Fri, 20 May 2016 11:06:45 +0200 Subject: [PATCH 12/19] MXSession: Detect when the access token is no more valid: Log it when it happens --- MatrixSDK/MXSession.m | 1 + 1 file changed, 1 insertion(+) diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index 4634e2d4f6..8aef9d4be1 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -687,6 +687,7 @@ - (void)serverSyncWithServerTimeout:(NSUInteger)serverTimeout MXError *mxError = [[MXError alloc] initWithNSError:error]; if ([mxError.errcode isEqualToString:kMXErrCodeStringUnknownToken]) { + NSLog(@"[MXSession] The access token is no more valid. Go to MXSessionStateUnknownToken state. Error: %@", error); [self setState:MXSessionStateUnknownToken]; // Do nothing more because without a valid access_token, the session is useless From 69f6eaa05f1785e202e69f9e2bdab9b308ad144d Mon Sep 17 00:00:00 2001 From: manuroe Date: Fri, 20 May 2016 16:31:36 +0200 Subject: [PATCH 13/19] Display all call events (invite, answer, hangup) --- MatrixSDK/JSONModels/MXJSONModels.h | 5 +++++ MatrixSDK/JSONModels/MXJSONModels.m | 5 +++++ MatrixSDK/VoIP/MXCall.m | 7 ++----- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/MatrixSDK/JSONModels/MXJSONModels.h b/MatrixSDK/JSONModels/MXJSONModels.h index a7b71dd84f..a37872deb2 100644 --- a/MatrixSDK/JSONModels/MXJSONModels.h +++ b/MatrixSDK/JSONModels/MXJSONModels.h @@ -1197,6 +1197,11 @@ FOUNDATION_EXPORT NSString *const kMXPushRuleScopeStringDevice; */ @property (nonatomic) NSUInteger lifetime; + /** + Indicate whether the invitation is for a video call. + */ + - (BOOL)isVideoCall; + @end /** diff --git a/MatrixSDK/JSONModels/MXJSONModels.m b/MatrixSDK/JSONModels/MXJSONModels.m index b261178e8c..90990dfd9d 100644 --- a/MatrixSDK/JSONModels/MXJSONModels.m +++ b/MatrixSDK/JSONModels/MXJSONModels.m @@ -1081,6 +1081,11 @@ + (id)modelFromJSON:(NSDictionary *)JSONDictionary return callInviteEventContent; } +- (BOOL)isVideoCall +{ + return (NSNotFound != [self.offer.sdp rangeOfString:@"m=video"].location); +} + @end @implementation MXCallCandidate diff --git a/MatrixSDK/VoIP/MXCall.m b/MatrixSDK/VoIP/MXCall.m index 9d9fa923a3..67bb9b0de1 100644 --- a/MatrixSDK/VoIP/MXCall.m +++ b/MatrixSDK/VoIP/MXCall.m @@ -111,11 +111,8 @@ - (void)handleCallEvent:(MXEvent *)event _callerId = event.sender; _isIncoming = YES; - // Determine if it is voice or video call - if (NSNotFound != [callInviteEventContent.offer.sdp rangeOfString:@"m=video"].location) - { - _isVideoCall = YES; - } + // Store if it is voice or video call + _isVideoCall = callInviteEventContent.isVideoCall; [callStackCall startCapturingMediaWithVideo:self.isVideoCall success:^{ [callStackCall handleOffer:callInviteEventContent.offer.sdp]; From c554e2b5f89a71567c88b524c75d4405b9df0283 Mon Sep 17 00:00:00 2001 From: manuroe Date: Fri, 20 May 2016 16:56:59 +0200 Subject: [PATCH 14/19] Display all call events (invite, answer, hangup): Force a MXFileStore clear --- MatrixSDK/Data/Store/MXFileStore/MXFileStore.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m b/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m index eb47d5468a..6c81a59156 100644 --- a/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m +++ b/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m @@ -20,7 +20,7 @@ #import "MXFileStoreMetaData.h" -NSUInteger const kMXFileVersion = 25; +NSUInteger const kMXFileVersion = 26; NSString *const kMXFileStoreFolder = @"MXFileStore"; NSString *const kMXFileStoreMedaDataFile = @"MXFileStore"; From 2e0ab2d6f614449f3862ad77af742308f52452e2 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 24 May 2016 15:23:03 +0100 Subject: [PATCH 15/19] Update links to push spec now it's fixed & released --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 00f650e211..d56b10ee2f 100644 --- a/README.rst +++ b/README.rst @@ -221,7 +221,7 @@ therefore requires a seperate server decoupled from the homeserver to send Push Notifications, as you cannot trust arbitrary homeservers with your application's APNS private key. This is called the 'Push Gateway'. More about how notifications work in Matrix can be found at -https://github.com/matrix-org/matrix-doc/blob/master/specification/42_push_overview.rst +http://matrix.org/docs/spec/push_gateway/unstable.html In simple terms, for your application to receive push notifications, you will need to set up a push gateway. This is a publicly accessible server specific @@ -231,7 +231,7 @@ which can be found at https://github.com/matrix-org/sygnal along with instructions on how to set it up. You can also write your own Push Gateway. See -https://github.com/matrix-org/matrix-doc/blob/master/specification/44_push_push_gw_api.rst +http://matrix.org/docs/spec/push_gateway/unstable.html for the specification on the HTTP Push Notification protocol. Your push gateway can listen for notifications on any path (as long as your app knows that path in order to inform the homeserver) but Matrix strongly recommends From e3a7016d2995528da8bf991ec7d4abab63212d48 Mon Sep 17 00:00:00 2001 From: giomfo Date: Thu, 26 May 2016 13:49:08 +0200 Subject: [PATCH 16/19] Add Copyright & License in README --- README.rst | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index d56b10ee2f..911da5e058 100644 --- a/README.rst +++ b/README.rst @@ -364,7 +364,17 @@ So, for now, you will be not be able to register a new account with the SDK on such homeserver. But you can login an existing user. If you run your own homeserver, the default launch parameters enables the -login-password type registration and you will be able to register a new user to -it. +login-password type registration and you will be able to register a new user to it. + +Copyright & License +================== + +Copyright (c) 2014-2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with the License. You may obtain a copy of the License in the LICENSE file, or at: + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. From b97a40b41c30c48a97b77ab6e28549db897ed525 Mon Sep 17 00:00:00 2001 From: giomfo Date: Fri, 27 May 2016 17:02:19 +0200 Subject: [PATCH 17/19] MXSession: Fix compilation warning --- MatrixSDK/MXSession.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index 8aef9d4be1..5e06bdd99c 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -1109,9 +1109,9 @@ - (MXRoom *)createRoom:(NSString *)roomId notify:(BOOL)notify return room; } -- (MXRoom *)createRoom:(NSString *)roomId withStateEvents:(NSArray*)stateEvents andAccountData:(MXRoomAccountData*)accountData notify:(BOOL)notify +- (MXRoom *)createRoom:(NSString *)roomId withStateEvents:(NSArray*)stateEvents andAccountData:(MXRoomAccountData*)theAccountData notify:(BOOL)notify { - MXRoom *room = [[MXRoom alloc] initWithRoomId:roomId andMatrixSession:self andStateEvents:stateEvents andAccountData:accountData]; + MXRoom *room = [[MXRoom alloc] initWithRoomId:roomId andMatrixSession:self andStateEvents:stateEvents andAccountData:theAccountData]; [self addRoom:room notify:notify]; return room; From e04b54b45f469fb30236737045a12efa69ff7849 Mon Sep 17 00:00:00 2001 From: giomfo Date: Wed, 1 Jun 2016 11:09:54 +0200 Subject: [PATCH 18/19] MXRoomState: disambiguate the display name for the invited room member too. Related to https://github.com/vector-im/vector-ios/issues/293 Room Participants - Search result: the user id should be displayed when 2 members has the same display name --- MatrixSDK/Data/MXRoomState.h | 3 ++- MatrixSDK/Data/MXRoomState.m | 34 ++++++++++++++++++---------------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/MatrixSDK/Data/MXRoomState.h b/MatrixSDK/Data/MXRoomState.h index 19c8498009..1c4a6847ed 100644 --- a/MatrixSDK/Data/MXRoomState.h +++ b/MatrixSDK/Data/MXRoomState.h @@ -187,7 +187,8 @@ A copy of the list of third party invites (actually MXRoomThirdPartyInvite insta /** Return a display name for a member. - It is his displayname member or, if nil, his userId + It is his displayname member or, if nil, his userId. + Disambiguate members who have the same displayname in the room by adding his userId. */ - (NSString*)memberName:(NSString*)userId; diff --git a/MatrixSDK/Data/MXRoomState.m b/MatrixSDK/Data/MXRoomState.m index 10af5c7475..9ef38f497d 100644 --- a/MatrixSDK/Data/MXRoomState.m +++ b/MatrixSDK/Data/MXRoomState.m @@ -518,35 +518,37 @@ - (NSString*)memberName:(NSString*)userId { // Get the user display name from the member list of the room MXRoomMember *member = [self memberWithUserId:userId]; - - // Do not consider null displayname - if (member && member.displayname.length) + + if (!member) + { + // The user may not have joined the room yet. So try to resolve display name from presence data + // Note: This data may not be available + MXUser* user = [mxSession userWithUserId:userId]; + if (user && user.displayname.length) + { + displayName = user.displayname; + } + } + else if (member.displayname.length) { displayName = member.displayname; + } + // Do not consider null displayname + if (displayName) + { // Disambiguate users who have the same displayname in the room for (MXRoomMember* member in members.allValues) { if ([member.displayname isEqualToString:displayName] && ![member.userId isEqualToString:userId]) { - displayName = [NSString stringWithFormat:@"%@(%@)", displayName, userId]; + displayName = [NSString stringWithFormat:@"%@ (%@)", displayName, userId]; break; } } } - - // The user may not have joined the room yet. So try to resolve display name from presence data - // Note: This data may not be available - if (!displayName) + else { - MXUser* user = [mxSession userWithUserId:userId]; - - if (user) { - displayName = user.displayname; - } - } - - if (!displayName) { // By default, use the user ID displayName = userId; } From 232a19ab25ce711c99e109f3abac1717ecc5be4e Mon Sep 17 00:00:00 2001 From: giomfo Date: Wed, 1 Jun 2016 17:35:25 +0200 Subject: [PATCH 19/19] Prepare matrix-ios-sdk release v0.6.8 --- CHANGES.rst | 14 ++++++++++++++ MatrixSDK.podspec | 4 ++-- MatrixSDK/MXSession.m | 2 +- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index cefc2cf685..5221044898 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,3 +1,17 @@ +Changes in Matrix iOS SDK in 0.6.8 (2016-06-01) +=============================================== + +Improvements: + * Push rules update: Listen to account_data to get push rules updates. + * SDK Tests improvements: Prevent the test suite from breaking because one test fails. + * MXRoomState: disambiguate the display name for the invited room member too. + +Bug fixes: + * Ignored users: kMXSessionIgnoredUsersDidChangeNotification was sometimes not sent. + * Recents: All blank after upgrade. + * Fixed implementation of userAccountData in MXMemoryStore and MXNoStore. + * MXSession: Detect when the access token is no more valid. + Changes in Matrix iOS SDK in 0.6.7 (2016-05-04) =============================================== diff --git a/MatrixSDK.podspec b/MatrixSDK.podspec index 58a340ca06..349dc07123 100644 --- a/MatrixSDK.podspec +++ b/MatrixSDK.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "MatrixSDK" - s.version = "0.6.7" + s.version = "0.6.8" s.summary = "The iOS SDK to build apps compatible with Matrix (http://www.matrix.org)" s.description = <<-DESC @@ -19,7 +19,7 @@ Pod::Spec.new do |s| s.platform = :ios, "7.0" - s.source = { :git => "https://github.com/matrix-org/matrix-ios-sdk.git", :tag => "v0.6.7" } + s.source = { :git => "https://github.com/matrix-org/matrix-ios-sdk.git", :tag => "v0.6.8" } s.source_files = "MatrixSDK", "MatrixSDK/**/*.{h,m}" s.resources = "MatrixSDK/Data/Store/MXCoreDataStore/*.xcdatamodeld" diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index 5e06bdd99c..7ee5aff57f 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -30,7 +30,7 @@ #pragma mark - Constants definitions -const NSString *MatrixSDKVersion = @"0.6.7"; +const NSString *MatrixSDKVersion = @"0.6.8"; NSString *const kMXSessionStateDidChangeNotification = @"kMXSessionStateDidChangeNotification"; NSString *const kMXSessionNewRoomNotification = @"kMXSessionNewRoomNotification"; NSString *const kMXSessionWillLeaveRoomNotification = @"kMXSessionWillLeaveRoomNotification";