Add background refresh to update conversation-list

Signed-off-by: Marcel Müller <marcel-mueller@gmx.de>
This commit is contained in:
Marcel Müller 2021-01-24 00:59:11 +01:00
Родитель 49cc45b9fd
Коммит 3ed50157ad
4 изменённых файлов: 132 добавлений и 2 удалений

Просмотреть файл

@ -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