diff --git a/src/MTXClient.h b/src/MTXClient.h index 476d73f..7b5dde7 100644 --- a/src/MTXClient.h +++ b/src/MTXClient.h @@ -142,6 +142,14 @@ typedef void (^mtx_client_room_join_block_t)(OFString *_Nullable roomID, storage: (id )storage OF_DESIGNATED_INITIALIZER; +/** + * @brief Performs a sync. + * + * @param block A block to call when a sync was performed + */ +- (void)syncWithTimeout: (of_time_interval_t)timeout + block: (mtx_client_response_block_t)block; + /** * @brief Logs out the device and invalidates the access token. * diff --git a/src/MTXClient.m b/src/MTXClient.m index d62ffd9..08907d5 100644 --- a/src/MTXClient.m +++ b/src/MTXClient.m @@ -29,6 +29,7 @@ #import "MTXLoginFailedException.h" #import "MTXLogoutFailedException.h" #import "MTXSendMessageFailedException.h" +#import "MTXSyncFailedException.h" static void validateHomeserver(OFURL *homeserver) @@ -195,6 +196,35 @@ validateHomeserver(OFURL *homeserver) homeserver: _homeserver]; } +- (void)syncWithTimeout: (of_time_interval_t)timeout + block: (mtx_client_response_block_t)block +{ + void *pool = objc_autoreleasePoolPush(); + MTXRequest *request = [self + requestWithPath: @"/_matrix/client/r0/sync"]; + unsigned long long timeoutMs = timeout * 1000; + request.query = [OFString stringWithFormat: @"timeout=%llu", timeoutMs]; + [request performWithBlock: ^ (mtx_response_t response, int statusCode, + id exception) { + if (exception != nil) { + block(exception); + return; + } + + if (statusCode != 200) { + block([MTXSyncFailedException + exceptionWithStatusCode: statusCode + response: response + client: self]); + return; + } + + block(nil); + }]; + + objc_autoreleasePoolPop(pool); +} + - (void)logOutWithBlock: (mtx_client_response_block_t)block { void *pool = objc_autoreleasePoolPush(); diff --git a/src/MTXRequest.h b/src/MTXRequest.h index 303f516..5bf3c93 100644 --- a/src/MTXRequest.h +++ b/src/MTXRequest.h @@ -70,6 +70,11 @@ typedef void (^mtx_request_block_t)(mtx_response_t _Nullable response, */ @property (copy, nonatomic) OFString *path; +/** + * @brief The query for the request. + */ +@property (copy, nullable, nonatomic) OFString *query; + /** * @brief An optional body to send along with the request. * diff --git a/src/MTXRequest.m b/src/MTXRequest.m index 0b8dd21..8f9ec38 100644 --- a/src/MTXRequest.m +++ b/src/MTXRequest.m @@ -97,6 +97,7 @@ OFMutableURL *requestURL = [[_homeserver mutableCopy] autorelease]; requestURL.path = _path; + requestURL.query = _query; OFMutableDictionary *headers = [OFMutableDictionary dictionary]; headers[@"User-Agent"] = @"ObjMatrix"; diff --git a/src/ObjMatrix.h b/src/ObjMatrix.h index 9ff8407..e42a9ac 100644 --- a/src/ObjMatrix.h +++ b/src/ObjMatrix.h @@ -25,8 +25,11 @@ #import "MTXSQLite3Storage.h" #import "MTXStorage.h" +#import "MTXClientException.h" #import "MTXFetchRoomListFailedException.h" #import "MTXJoinRoomFailedException.h" #import "MTXLeaveRoomFailedException.h" #import "MTXLoginFailedException.h" #import "MTXLogoutFailedException.h" +#import "MTXSendMessageFailedException.h" +#import "MTXSyncFailedException.h" diff --git a/src/exceptions/MTXFetchRoomListFailedException.m b/src/exceptions/MTXFetchRoomListFailedException.m index 4f0c158..60eb29f 100644 --- a/src/exceptions/MTXFetchRoomListFailedException.m +++ b/src/exceptions/MTXFetchRoomListFailedException.m @@ -28,7 +28,7 @@ - (OFString *)description { return [OFString stringWithFormat: - @"Failed to fetch room list for %@: %@", - self.client.userID, self.response]; + @"Failed to fetch room list for %@ with status code %d: %@", + self.client.userID, self.statusCode, self.response]; } @end diff --git a/src/exceptions/MTXJoinRoomFailedException.m b/src/exceptions/MTXJoinRoomFailedException.m index 3b83b3b..eec94df 100644 --- a/src/exceptions/MTXJoinRoomFailedException.m +++ b/src/exceptions/MTXJoinRoomFailedException.m @@ -65,7 +65,7 @@ - (OFString *)description { return [OFString stringWithFormat: - @"Failed to join room %@ for %@: %@", - _room, self.client.userID, self.response]; + @"Failed to join room %@ for %@ with status code %d: %@", + _room, self.client.userID, self.statusCode, self.response]; } @end diff --git a/src/exceptions/MTXLeaveRoomFailedException.m b/src/exceptions/MTXLeaveRoomFailedException.m index 558f486..28a3cab 100644 --- a/src/exceptions/MTXLeaveRoomFailedException.m +++ b/src/exceptions/MTXLeaveRoomFailedException.m @@ -65,7 +65,7 @@ - (OFString *)description { return [OFString stringWithFormat: - @"Failed to leave room %@ for %@: %@", - _roomID, self.client.userID, self.response]; + @"Failed to leave room %@ for %@ with status code %d: %@", + _roomID, self.client.userID, self.statusCode, self.response]; } @end diff --git a/src/exceptions/MTXLoginFailedException.m b/src/exceptions/MTXLoginFailedException.m index aa1257f..aba4440 100644 --- a/src/exceptions/MTXLoginFailedException.m +++ b/src/exceptions/MTXLoginFailedException.m @@ -66,7 +66,7 @@ - (OFString *)description { return [OFString stringWithFormat: - @"Failed to log in user %@ on %@: %@", - _user, _homeserver, _response]; + @"Failed to log in user %@ on %@ with status code %d: %@", + _user, _homeserver, _statusCode, _response]; } @end diff --git a/src/exceptions/MTXLogoutFailedException.m b/src/exceptions/MTXLogoutFailedException.m index f87c9fa..c1d1158 100644 --- a/src/exceptions/MTXLogoutFailedException.m +++ b/src/exceptions/MTXLogoutFailedException.m @@ -28,7 +28,7 @@ - (OFString *)description { return [OFString stringWithFormat: - @"Failed to log out user %@: %@", - self.client.userID, self.response]; + @"Failed to log out user %@ with status code: %@", + self.client.userID, self.statusCode, self.response]; } @end diff --git a/src/exceptions/MTXSendMessageFailedException.m b/src/exceptions/MTXSendMessageFailedException.m index 8409ad6..a9531e0 100644 --- a/src/exceptions/MTXSendMessageFailedException.m +++ b/src/exceptions/MTXSendMessageFailedException.m @@ -70,7 +70,7 @@ - (OFString *)description { return [OFString stringWithFormat: - @"Failed to send message to room %@ for %@: %@", - _roomID, self.client.userID, self.response]; + @"Failed to send message to room %@ for %@ with status code %d: %@", + _roomID, self.client.userID, self.statusCode, self.response]; } @end diff --git a/src/exceptions/MTXSyncFailedException.h b/src/exceptions/MTXSyncFailedException.h new file mode 100644 index 0000000..02d9084 --- /dev/null +++ b/src/exceptions/MTXSyncFailedException.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2020, Jonathan Schleifer + * + * https://fossil.nil.im/objmatrix + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice is present in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#import + +#import "MTXClientException.h" + +OF_ASSUME_NONNULL_BEGIN + +@interface MTXSyncFailedException: MTXClientException +@end + +OF_ASSUME_NONNULL_END diff --git a/src/exceptions/MTXSyncFailedException.m b/src/exceptions/MTXSyncFailedException.m new file mode 100644 index 0000000..ab66805 --- /dev/null +++ b/src/exceptions/MTXSyncFailedException.m @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2020, Jonathan Schleifer + * + * https://fossil.nil.im/objmatrix + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice is present in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#import "MTXSyncFailedException.h" + +#import "MTXClient.h" + +@implementation MTXSyncFailedException +- (OFString *)description +{ + return [OFString stringWithFormat: + @"Failed to sync for user %@ with status code %d: %@", + self.client.userID, self.statusCode, self.response]; +} +@end diff --git a/src/exceptions/Makefile b/src/exceptions/Makefile index bc23e67..99ec833 100644 --- a/src/exceptions/Makefile +++ b/src/exceptions/Makefile @@ -9,7 +9,8 @@ SRCS = MTXClientException.m \ MTXLeaveRoomFailedException.m \ MTXLoginFailedException.m \ MTXLogoutFailedException.m \ - MTXSendMessageFailedException.m + MTXSendMessageFailedException.m \ + MTXSyncFailedException.m INCLUDES = ${SRCS:.m=.h} include ../../buildsys.mk diff --git a/tests/tests.m b/tests/tests.m index c49abf4..6102f50 100644 --- a/tests/tests.m +++ b/tests/tests.m @@ -62,6 +62,21 @@ OF_APPLICATION_DELEGATE(Tests) _client = [client retain]; of_log(@"Logged in client: %@", _client); + [self sync]; + }]; +} + +- (void)sync +{ + [_client syncWithTimeout: 5 + block: ^ (id exception) { + if (exception != nil) { + of_log(@"Failed to sync: %@", exception); + [OFApplication terminateWithStatus: 1]; + } + + of_log(@"Synced"); + [self fetchRoomList]; }]; }