diff --git a/apps/ios/Shared/Model/SimpleXAPI.swift b/apps/ios/Shared/Model/SimpleXAPI.swift index 4e24c616d9..3abd1e92d1 100644 --- a/apps/ios/Shared/Model/SimpleXAPI.swift +++ b/apps/ios/Shared/Model/SimpleXAPI.swift @@ -1218,8 +1218,8 @@ func apiEndCall(_ contact: Contact) async throws { try await sendCommandOkResp(.apiEndCall(contact: contact)) } -func apiGetCallInvitations() async throws -> [RcvCallInvitation] { - let r = await chatSendCmd(.apiGetCallInvitations) +func apiGetCallInvitations() throws -> [RcvCallInvitation] { + let r = chatSendCmdSync(.apiGetCallInvitations) if case let .callInvitations(invs) = r { return invs } throw r } @@ -1517,7 +1517,7 @@ func startChat(refreshInvitations: Bool = true) throws { try getUserChatData() NtfManager.shared.setNtfBadgeCount(m.totalUnreadCountForAllUsers()) if (refreshInvitations) { - Task { try await refreshCallInvitations() } + try refreshCallInvitations() } (m.savedToken, m.tokenStatus, m.notificationMode, m.notificationServer) = apiGetNtfToken() _ = try apiStartChat() @@ -2161,25 +2161,22 @@ func chatItemSimpleUpdate(_ user: any UserLike, _ aChatItem: AChatItem) async { } } -func refreshCallInvitations() async throws { +func refreshCallInvitations() throws { let m = ChatModel.shared - let callInvitations = try await justRefreshCallInvitations() + let callInvitations = try justRefreshCallInvitations() if let (chatId, ntfAction) = m.ntfCallInvitationAction, let invitation = m.callInvitations.removeValue(forKey: chatId) { - await MainActor.run { m.ntfCallInvitationAction = nil } + m.ntfCallInvitationAction = nil CallController.shared.callAction(invitation: invitation, action: ntfAction) } else if let invitation = callInvitations.last(where: { $0.user.showNotifications }) { activateCall(invitation) } } -func justRefreshCallInvitations() async throws -> [RcvCallInvitation] { +func justRefreshCallInvitations() throws -> [RcvCallInvitation] { let m = ChatModel.shared - let callInvitations = try await apiGetCallInvitations() - await MainActor.run { - m.callInvitations = callInvitations - .reduce(into: [ChatId: RcvCallInvitation]()) { result, inv in result[inv.contact.id] = inv } - } + let callInvitations = try apiGetCallInvitations() + m.callInvitations = callInvitations.reduce(into: [ChatId: RcvCallInvitation]()) { result, inv in result[inv.contact.id] = inv } return callInvitations } diff --git a/apps/ios/Shared/SimpleXApp.swift b/apps/ios/Shared/SimpleXApp.swift index 7f2c3b5866..621f58dc0c 100644 --- a/apps/ios/Shared/SimpleXApp.swift +++ b/apps/ios/Shared/SimpleXApp.swift @@ -83,11 +83,9 @@ struct SimpleXApp: App { if appState != .stopped { startChatAndActivate { if appState.inactive && chatModel.chatRunning == true { - Task { - await updateChats() - if !chatModel.showCallView && !CallController.shared.hasActiveCalls() { - await updateCallInvitations() - } + updateChats() + if !chatModel.showCallView && !CallController.shared.hasActiveCalls() { + updateCallInvitations() } } } @@ -132,16 +130,16 @@ struct SimpleXApp: App { } } - private func updateChats() async { + private func updateChats() { do { - let chats = try await apiGetChatsAsync() - await MainActor.run { chatModel.updateChats(chats) } + let chats = try apiGetChats() + chatModel.updateChats(chats) if let id = chatModel.chatId, let chat = chatModel.getChat(id) { Task { await loadChat(chat: chat, clearItems: false) } } if let ncr = chatModel.ntfContactRequest { - await MainActor.run { chatModel.ntfContactRequest = nil } + chatModel.ntfContactRequest = nil if case let .contactRequest(contactRequest) = chatModel.getChat(ncr.chatId)?.chatInfo { Task { await acceptContactRequest(incognito: ncr.incognito, contactRequest: contactRequest) } } @@ -151,9 +149,9 @@ struct SimpleXApp: App { } } - private func updateCallInvitations() async { + private func updateCallInvitations() { do { - try await refreshCallInvitations() + try refreshCallInvitations() } catch let error { logger.error("apiGetCallInvitations: cannot update call invitations \(responseError(error))") } diff --git a/apps/ios/Shared/Views/Call/CallController.swift b/apps/ios/Shared/Views/Call/CallController.swift index 4fcc7db4e1..64b565e8e6 100644 --- a/apps/ios/Shared/Views/Call/CallController.swift +++ b/apps/ios/Shared/Views/Call/CallController.swift @@ -186,30 +186,29 @@ class CallController: NSObject, CXProviderDelegate, PKPushRegistryDelegate, Obse logger.debug("CallController: started chat") self.shouldSuspendChat = true // There are no invitations in the model, as it was processed by NSE - Task { - _ = try? await justRefreshCallInvitations() - logger.debug("CallController: updated call invitations chat") - // logger.debug("CallController justRefreshCallInvitations: \(String(describing: m.callInvitations))") - // Extract the call information from the push notification payload - let m = ChatModel.shared - if let contactId = payload.dictionaryPayload["contactId"] as? String, - let invitation = m.callInvitations[contactId] { + _ = try? justRefreshCallInvitations() + logger.debug("CallController: updated call invitations chat") + // logger.debug("CallController justRefreshCallInvitations: \(String(describing: m.callInvitations))") + // Extract the call information from the push notification payload + let m = ChatModel.shared + if let contactId = payload.dictionaryPayload["contactId"] as? String, + let invitation = m.callInvitations[contactId] { + let update = self.cxCallUpdate(invitation: invitation) + if let uuid = invitation.callkitUUID { + logger.debug("CallController: report pushkit call via CallKit") let update = self.cxCallUpdate(invitation: invitation) - if let uuid = invitation.callkitUUID { - logger.debug("CallController: report pushkit call via CallKit") - let update = self.cxCallUpdate(invitation: invitation) - do { - try await self.provider.reportNewIncomingCall(with: uuid, update: update) - } catch { - _ = await MainActor.run { m.callInvitations.removeValue(forKey: contactId) } + self.provider.reportNewIncomingCall(with: uuid, update: update) { error in + if error != nil { + m.callInvitations.removeValue(forKey: contactId) } + // Tell PushKit that the notification is handled. completion() - } else { - self.reportExpiredCall(update: update, completion) } } else { - self.reportExpiredCall(payload: payload, completion) + self.reportExpiredCall(update: update, completion) } + } else { + self.reportExpiredCall(payload: payload, completion) } } diff --git a/apps/ios/Shared/Views/ChatList/UserPicker.swift b/apps/ios/Shared/Views/ChatList/UserPicker.swift index e1b2356bed..eeb7bf14f4 100644 --- a/apps/ios/Shared/Views/ChatList/UserPicker.swift +++ b/apps/ios/Shared/Views/ChatList/UserPicker.swift @@ -85,16 +85,13 @@ struct UserPicker: View { .padding(8) .opacity(userPickerVisible ? 1.0 : 0.0) .onAppear { - // This check prevents the call of listUsers after the app is suspended, and the database is closed. - if case .active = scenePhase { - Task { - do { - let users = try await listUsersAsync() - await MainActor.run { m.users = users } - } catch { - logger.error("Error loading users \(responseError(error))") - } + do { + // This check prevents the call of listUsers after the app is suspended, and the database is closed. + if case .active = scenePhase { + m.users = try listUsers() } + } catch let error { + logger.error("Error loading users \(responseError(error))") } } }