@@ -46,10 +46,14 @@ homeserver.query != nil || homeserver.fragment != nil) @throw [OFInvalidArgumentException exception]; } @implementation MTXClient +{ + bool _syncing; +} + + (instancetype)clientWithUserID: (OFString *)userID deviceID: (OFString *)deviceID accessToken: (OFString *)accessToken homeserver: (OFURL *)homeserver storage: (id )storage @@ -156,10 +160,11 @@ _userID = [userID copy]; _deviceID = [deviceID copy]; _accessToken = [accessToken copy]; _homeserver = [homeserver copy]; _storage = [storage retain]; + _syncTimeout = 300; } @catch (id e) { [self release]; @throw e; } @@ -194,40 +199,48 @@ return [MTXRequest requestWithPath: path accessToken: _accessToken homeserver: _homeserver]; } -- (void)syncWithTimeout: (of_time_interval_t)timeout - block: (mtx_client_response_block_t)block +- (void)startSyncLoop { + if (_syncing) + return; + + _syncing = true; + void *pool = objc_autoreleasePoolPush(); MTXRequest *request = [self requestWithPath: @"/_matrix/client/r0/sync"]; - unsigned long long timeoutMs = timeout * 1000; + unsigned long long timeoutMs = _syncTimeout * 1000; OFMutableDictionary *query = [OFMutableDictionary dictionaryWithObject: @(timeoutMs).stringValue forKey: @"timeout"]; query[@"since"] = [_storage nextBatchForDeviceID: _deviceID]; request.query = query; [request performWithBlock: ^ (mtx_response_t response, int statusCode, id exception) { if (exception != nil) { - block(exception); + if (_syncExceptionHandler != NULL) + _syncExceptionHandler(exception); return; } if (statusCode != 200) { - block([MTXSyncFailedException - exceptionWithStatusCode: statusCode - response: response - client: self]); + if (_syncExceptionHandler != NULL) + _syncExceptionHandler([MTXSyncFailedException + exceptionWithStatusCode: statusCode + response: response + client: self]); return; } OFString *nextBatch = response[@"next_batch"]; if (![nextBatch isKindOfClass: OFString.class]) { - block([OFInvalidServerReplyException exception]); + if (_syncExceptionHandler != NULL) + _syncExceptionHandler( + [OFInvalidServerReplyException exception]); return; } @try { [_storage transactionWithBlock: ^ { @@ -243,19 +256,26 @@ response[@"to_device"]]; return true; }]; } @catch (id e) { - block(e); + if (_syncExceptionHandler != NULL) + _syncExceptionHandler(e); return; } - block(nil); + if (_syncing) + [self startSyncLoop]; }]; objc_autoreleasePoolPop(pool); } + +- (void)stopSyncLoop +{ + _syncing = false; +} - (void)logOutWithBlock: (mtx_client_response_block_t)block { void *pool = objc_autoreleasePoolPush(); MTXRequest *request =