зеркало из https://github.com/nextcloud/talk-ios.git
Add background refresh to update conversation-list
Signed-off-by: Marcel Müller <marcel-mueller@gmx.de>
This commit is contained in:
Родитель
49cc45b9fd
Коммит
3ed50157ad
|
@ -32,6 +32,10 @@
|
|||
|
||||
#import <UserNotifications/UserNotifications.h>
|
||||
|
||||
#import <BackgroundTasks/BGTaskScheduler.h>
|
||||
#import <BackgroundTasks/BGTaskRequest.h>
|
||||
#import <BackgroundTasks/BGTask.h>
|
||||
|
||||
#import "NCAudioController.h"
|
||||
#import "NCAppBranding.h"
|
||||
#import "NCConnectionController.h"
|
||||
|
@ -82,6 +86,8 @@
|
|||
[[BKPasscodeLockScreenManager sharedManager] showLockScreen:NO];
|
||||
});
|
||||
|
||||
[self registerBackgroundFetchTask];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
@ -112,6 +118,10 @@
|
|||
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
|
||||
// show passcode view controller when enter background. Screen will be obscured from here.
|
||||
[[BKPasscodeLockScreenManager sharedManager] showLockScreen:NO];
|
||||
|
||||
if (@available(iOS 13.0, *)) {
|
||||
[self scheduleAppRefresh];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -308,4 +318,66 @@
|
|||
return navigationController;
|
||||
}
|
||||
|
||||
#pragma mark - BackgroundFetch / AppRefresh
|
||||
|
||||
- (void)registerBackgroundFetchTask {
|
||||
NSString *refreshTaskIdentifier = [NSString stringWithFormat:@"%@.refresh", NSBundle.mainBundle.bundleIdentifier];
|
||||
|
||||
if (@available(iOS 13.0, *)) {
|
||||
// see: https://developer.apple.com/documentation/backgroundtasks/bgtaskscheduler?language=objc
|
||||
[[BGTaskScheduler sharedScheduler] registerForTaskWithIdentifier:refreshTaskIdentifier
|
||||
usingQueue:nil
|
||||
launchHandler:^(__kindof BGTask * _Nonnull task) {
|
||||
[self handleAppRefresh:task];
|
||||
}];
|
||||
} else {
|
||||
[UIApplication.sharedApplication setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)scheduleAppRefresh API_AVAILABLE(ios(13.0))
|
||||
{
|
||||
NSString *refreshTaskIdentifier = [NSString stringWithFormat:@"%@.refresh", NSBundle.mainBundle.bundleIdentifier];
|
||||
|
||||
BGAppRefreshTaskRequest *request = [[BGAppRefreshTaskRequest alloc] initWithIdentifier:refreshTaskIdentifier];
|
||||
request.earliestBeginDate = [NSDate dateWithTimeIntervalSinceNow:UIApplicationBackgroundFetchIntervalMinimum];
|
||||
|
||||
NSError *error = nil;
|
||||
[[BGTaskScheduler sharedScheduler] submitTaskRequest:request error:&error];
|
||||
|
||||
if (error) {
|
||||
NSLog(@"Failed to submit apprefresh request: %@", error);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)handleAppRefresh:(BGTask *)task API_AVAILABLE(ios(13.0))
|
||||
{
|
||||
NSLog(@"Performing background fetch -> handleAppRefresh");
|
||||
|
||||
// With BGTasks (iOS >= 13) we need to schedule another refresh when running in background
|
||||
[self scheduleAppRefresh];
|
||||
|
||||
[[NCRoomsManager sharedInstance] updateRoomsAndChatsUpdatingUserStatus:NO withCompletionBlock:^(NSError *error) {
|
||||
if (error) {
|
||||
[task setTaskCompletedWithSuccess:NO];
|
||||
} else {
|
||||
[task setTaskCompletedWithSuccess:YES];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
|
||||
{
|
||||
NSLog(@"Performing background fetch -> performFetchWithCompletionHandler");
|
||||
|
||||
[[NCRoomsManager sharedInstance] updateRoomsAndChatsUpdatingUserStatus:NO withCompletionBlock:^(NSError *error) {
|
||||
if (error) {
|
||||
completionHandler(UIBackgroundFetchResultFailed);
|
||||
} else {
|
||||
completionHandler(UIBackgroundFetchResultNewData);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
<key>BGTaskSchedulerPermittedIdentifiers</key>
|
||||
<array>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER).refresh</string>
|
||||
</array>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
|
|
|
@ -35,6 +35,9 @@ extern NSString * const NCRoomsManagerDidUpdateRoomNotification;
|
|||
// Call
|
||||
extern NSString * const NCRoomsManagerDidStartCallNotification;
|
||||
|
||||
typedef void (^UpdateRoomsCompletionBlock)(NSArray *roomsWithNewMessages, NSError *error);
|
||||
typedef void (^UpdateRoomsAndChatsCompletionBlock)(NSError *error);
|
||||
|
||||
@interface NCRoomController : NSObject
|
||||
|
||||
@property (nonatomic, strong) NSString *userSessionId;
|
||||
|
@ -52,6 +55,7 @@ extern NSString * const NCRoomsManagerDidStartCallNotification;
|
|||
// Room
|
||||
- (NSArray *)roomsForAccountId:(NSString *)accountId witRealm:(RLMRealm *)realm;
|
||||
- (NCRoom *)roomWithToken:(NSString *)token forAccountId:(NSString *)accountId;
|
||||
- (void)updateRoomsAndChatsUpdatingUserStatus:(BOOL)updateStatus withCompletionBlock:(UpdateRoomsAndChatsCompletionBlock)block;
|
||||
- (void)updateRoomsUpdatingUserStatus:(BOOL)updateStatus;
|
||||
- (void)updateRoom:(NSString *)token;
|
||||
- (void)updateRoomLocal:(NCRoom *) room;
|
||||
|
|
|
@ -292,18 +292,58 @@ NSString * const NCRoomsManagerDidReceiveChatMessagesNotification = @"ChatMess
|
|||
}
|
||||
|
||||
- (void)updateRoomsUpdatingUserStatus:(BOOL)updateStatus
|
||||
{
|
||||
[self updateRoomsUpdatingUserStatus:updateStatus withCompletionBlock:nil];
|
||||
}
|
||||
|
||||
- (void)updateRoomsAndChatsUpdatingUserStatus:(BOOL)updateStatus withCompletionBlock:(UpdateRoomsAndChatsCompletionBlock)block
|
||||
{
|
||||
[self updateRoomsUpdatingUserStatus:updateStatus withCompletionBlock:^(NSArray *roomsWithNewMessages, NSError *error) {
|
||||
if (error) {
|
||||
if (block) {
|
||||
block(error);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
NSLog(@"Finished rooms update with %ld rooms with new messages", [roomsWithNewMessages count]);
|
||||
dispatch_group_t chatUpdateGroup = dispatch_group_create();
|
||||
|
||||
for (NCRoom *room in roomsWithNewMessages) {
|
||||
//TODO: Update chat in rooms
|
||||
}
|
||||
|
||||
dispatch_group_notify(chatUpdateGroup, dispatch_get_main_queue(), ^{
|
||||
// Notify backgroundFetch that we're finished
|
||||
if (block) {
|
||||
block(nil);
|
||||
}
|
||||
});
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)updateRoomsUpdatingUserStatus:(BOOL)updateStatus withCompletionBlock:(UpdateRoomsCompletionBlock)block
|
||||
{
|
||||
TalkAccount *activeAccount = [[NCDatabaseManager sharedInstance] activeAccount];
|
||||
[[NCAPIController sharedInstance] getRoomsForAccount:activeAccount updateStatus:updateStatus withCompletionBlock:^(NSArray *rooms, NSError *error, NSInteger statusCode) {
|
||||
NSMutableDictionary *userInfo = [NSMutableDictionary new];
|
||||
NSMutableArray *roomsWithNewMessages = [NSMutableArray new];
|
||||
|
||||
if (!error) {
|
||||
RLMRealm *realm = [RLMRealm defaultRealm];
|
||||
[realm transactionWithBlock:^{
|
||||
// Add or update rooms
|
||||
NSInteger updateTimestamp = [[NSDate date] timeIntervalSince1970];
|
||||
for (NSDictionary *roomDict in rooms) {
|
||||
[self updateRoomWithDict:roomDict withAccount:activeAccount withTimestamp:updateTimestamp withRealm:realm];
|
||||
BOOL roomContainsNewMessages = [self updateRoomWithDict:roomDict withAccount:activeAccount withTimestamp:updateTimestamp withRealm:realm];
|
||||
|
||||
if (roomContainsNewMessages) {
|
||||
NCRoom *room = [NCRoom roomWithDictionary:roomDict andAccountId:activeAccount.accountId];
|
||||
[roomsWithNewMessages addObject:room];
|
||||
}
|
||||
}
|
||||
|
||||
// Delete old rooms
|
||||
NSPredicate *query = [NSPredicate predicateWithFormat:@"accountId = %@ AND lastUpdate != %ld", activeAccount.accountId, (long)updateTimestamp];
|
||||
RLMResults *managedRoomsToBeDeleted = [NCRoom objectsWithPredicate:query];
|
||||
|
@ -320,9 +360,14 @@ NSString * const NCRoomsManagerDidReceiveChatMessagesNotification = @"ChatMess
|
|||
[userInfo setObject:error forKey:@"error"];
|
||||
NSLog(@"Could not update rooms. Error: %@", error.description);
|
||||
}
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:NCRoomsManagerDidUpdateRoomsNotification
|
||||
object:self
|
||||
userInfo:userInfo];
|
||||
|
||||
if (block) {
|
||||
block(roomsWithNewMessages, error);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
|
@ -349,8 +394,10 @@ NSString * const NCRoomsManagerDidReceiveChatMessagesNotification = @"ChatMess
|
|||
}];
|
||||
}
|
||||
|
||||
- (void)updateRoomWithDict:(NSDictionary *)roomDict withAccount:(TalkAccount *)activeAccount withTimestamp:(NSInteger)timestamp withRealm:(RLMRealm *)realm
|
||||
- (BOOL)updateRoomWithDict:(NSDictionary *)roomDict withAccount:(TalkAccount *)activeAccount withTimestamp:(NSInteger)timestamp withRealm:(RLMRealm *)realm
|
||||
{
|
||||
BOOL roomContainsNewMessages = NO;
|
||||
|
||||
NCRoom *room = [NCRoom roomWithDictionary:roomDict andAccountId:activeAccount.accountId];
|
||||
NSDictionary *messageDict = [roomDict objectForKey:@"lastMessage"];
|
||||
NCChatMessage *lastMessage = [NCChatMessage messageWithDictionary:messageDict andAccountId:activeAccount.accountId];
|
||||
|
@ -359,6 +406,10 @@ NSString * const NCRoomsManagerDidReceiveChatMessagesNotification = @"ChatMess
|
|||
|
||||
NCRoom *managedRoom = [NCRoom objectsWhere:@"internalId = %@", room.internalId].firstObject;
|
||||
if (managedRoom) {
|
||||
if (room.lastActivity > managedRoom.lastActivity) {
|
||||
roomContainsNewMessages = YES;
|
||||
}
|
||||
|
||||
[NCRoom updateRoom:managedRoom withRoom:room];
|
||||
} else if (room) {
|
||||
[realm addObject:room];
|
||||
|
@ -371,6 +422,8 @@ NSString * const NCRoomsManagerDidReceiveChatMessagesNotification = @"ChatMess
|
|||
NCChatController *chatController = [[NCChatController alloc] initForRoom:room];
|
||||
[chatController storeMessages:@[messageDict] withRealm:realm];
|
||||
}
|
||||
|
||||
return roomContainsNewMessages;
|
||||
}
|
||||
|
||||
- (void)updateRoomLocal:(NCRoom *)room
|
||||
|
|
Загрузка…
Ссылка в новой задаче