Post

Replies

Boosts

Views

Activity

Reply to Run async tasks using Background Tasks
HI @eskimo, Thanks for chiming in and providing insight. Using the below, I set a breakpoint right when the app is moved to the background (I'm not using appDelegate). .onReceive(NotificationCenter.default.publisher(for: UIApplication.didEnterBackgroundNotification)) { _ in       backgroundTaskManager.scheduleAppRefresh() // <= breakpoint here     } Once the app is paused, in Xcode, I run the following command in the Xcode terminal: e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.example.task"] That responds with: 2021-12-07 05:29:25.405222+0700 App[602:49934] Simulating launch for task with identifier com.example.task After that, I resume the app in Xcode and see (I believe "missing data" is not an error below): 2021-12-07 05:29:29.724492+0700 App[602:50205] Starting simulated task: <decode: missing data> Followed by the initial operation of the getUpdateAppData() function being called. The initial operation is a function that runs an Amplify (iOS library) graphQL query (here's an excerpt): func getMyFriends(currentUser: User) async throws -> [Friend] {     Logger.log(.fetch, "Fetching \(currentUser.username)'s friends...")     return try await withCheckedThrowingContinuation { continuation in       let friend = Friend.keys       let predicate = friend.owner == currentUser.username       Amplify.API.query(request: .list(Friend.self, where: predicate)) { event in         switch event {         case .success(let result): ... The app seems to just stop right after the logging of "Fetching (currentUser.username)'s friends..." No errors are thrown that I can see. Note this function works fine when it's called when the app is in the foreground. Also, when I return the app to the foreground, the getUpdateAppData() tries to resume, and rarely (if ever) completes as it should: 🐕 Fetching Elmer's friends... 2021-12-07 06:02:20.150514+0700 App[654:65556] Connection 1: encountered error(1:53) // <= upon return to foreground 2021-12-07 06:02:20.150650+0700 App[654:65556] Connection 1: received failure notification 2021-12-07 06:02:20.151257+0700 App[654:65556] [connection] nw_connection_copy_connected_local_endpoint [C1] Connection has no connected path 2021-12-07 06:02:20.151450+0700 App[654:65556] [connection] nw_connection_copy_connected_remote_endpoint [C1] Connection has no connected path 2021-12-07 06:02:20.153068+0700 App[654:65556] Connection 2: encountered error(1:53) 2021-12-07 06:02:20.153125+0700 App[654:65556] Connection 2: received failure notification 2021-12-07 06:02:20.153280+0700 App[654:65556] [connection] nw_connection_copy_connected_local_endpoint [C2] Connection has no connected path 2021-12-07 06:02:20.153891+0700 App[654:65556] [connection] nw_connection_copy_connected_remote_endpoint [C2] Connection has no connected path 2021-12-07 06:02:20.155082+0700 App[654:65556] Connection 3: encountered error(1:53) 2021-12-07 06:02:20.155293+0700 App[654:65556] Connection 3: received failure notification 2021-12-07 06:02:20.161795+0700 App[654:65556] [connection] nw_connection_copy_connected_local_endpoint [C3] Connection has no connected path 2021-12-07 06:02:20.161877+0700 App[654:65556] [connection] nw_connection_copy_connected_remote_endpoint [C3] Connection has no connected path 🦴 Successfully fetched Elmer's friends! ... Maybe Amplify doesn't work when in the background? I dunno. One thing that I have yet to try is testing with a simple, single API operation in lieu of the somewhat more involved getUpdateAppData() function that is currently running through completion. Any further thoughts and/or advice is appreciated. private func configureBackgroundTasks() { Logger.log(.info, "Registering background tasks...") let bgTaskIdentifier = "com.example.task" BGTaskScheduler.shared.register(forTaskWithIdentifier: bgTaskIdentifier, using: DispatchQueue.main) { (task) in Logger.log(.info, "Performing background task \(bgTaskIdentifier)") Task { if let updatedData = await appManager.getUpdateAppData() { DispatchQueue.main.async { appManager.data = updatedData task.setTaskCompleted(success: true) } } else { task.setTaskCompleted(success: false) } backgroundTaskManager.scheduleAppRefresh() } } }
Topic: App & System Services SubTopic: Core OS Tags:
Dec ’21
Reply to Run async tasks using Background Tasks
Hi @OOPer, Thanks much for taking the time to respond. I have tried several variations, in an attempt to get this working. The result from your suggested mods: using Task instead of Task.init and putting task.setTaskCompleted(success: true) in a DispatchQueue.main.async {}, results in: 2021-12-04 14:58:39.136393-0800 App[8341:2562502] [connection] nw_read_request_report [C7] Receive failed with error "Socket is not connected" 2021-12-04 14:58:39.139668-0800 App[8341:2562502] [connection] nw_read_request_report [C7] Receive failed with error "Socket is not connected" Doing the same, but using Task.init {... results in: 2021-12-04 15:03:53.128265-0800 App[8344:2563988] [Framework] Task <BGAppRefreshTask: com.example.task> dealloc'd without completing. This is a programmer error. 2021-12-04 15:03:53.128610-0800 App[8344:2563988] Marking simulated task complete: (null) I do like the very specific calling out the programmer error 😄 I've also tried using BGProcessingTaskRequest instead of BGAppRefreshTaskRequest just in case the update operation was timing out after 30 seconds, which I believe is the time window alloted for a refresh task.
Topic: App & System Services SubTopic: Core OS Tags:
Dec ’21
Reply to Run async tasks using Background Tasks
HI @eskimo, Thanks for chiming in and providing insight. Using the below, I set a breakpoint right when the app is moved to the background (I'm not using appDelegate). .onReceive(NotificationCenter.default.publisher(for: UIApplication.didEnterBackgroundNotification)) { _ in       backgroundTaskManager.scheduleAppRefresh() // <= breakpoint here     } Once the app is paused, in Xcode, I run the following command in the Xcode terminal: e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.example.task"] That responds with: 2021-12-07 05:29:25.405222+0700 App[602:49934] Simulating launch for task with identifier com.example.task After that, I resume the app in Xcode and see (I believe "missing data" is not an error below): 2021-12-07 05:29:29.724492+0700 App[602:50205] Starting simulated task: <decode: missing data> Followed by the initial operation of the getUpdateAppData() function being called. The initial operation is a function that runs an Amplify (iOS library) graphQL query (here's an excerpt): func getMyFriends(currentUser: User) async throws -> [Friend] {     Logger.log(.fetch, "Fetching \(currentUser.username)'s friends...")     return try await withCheckedThrowingContinuation { continuation in       let friend = Friend.keys       let predicate = friend.owner == currentUser.username       Amplify.API.query(request: .list(Friend.self, where: predicate)) { event in         switch event {         case .success(let result): ... The app seems to just stop right after the logging of "Fetching (currentUser.username)'s friends..." No errors are thrown that I can see. Note this function works fine when it's called when the app is in the foreground. Also, when I return the app to the foreground, the getUpdateAppData() tries to resume, and rarely (if ever) completes as it should: 🐕 Fetching Elmer's friends... 2021-12-07 06:02:20.150514+0700 App[654:65556] Connection 1: encountered error(1:53) // <= upon return to foreground 2021-12-07 06:02:20.150650+0700 App[654:65556] Connection 1: received failure notification 2021-12-07 06:02:20.151257+0700 App[654:65556] [connection] nw_connection_copy_connected_local_endpoint [C1] Connection has no connected path 2021-12-07 06:02:20.151450+0700 App[654:65556] [connection] nw_connection_copy_connected_remote_endpoint [C1] Connection has no connected path 2021-12-07 06:02:20.153068+0700 App[654:65556] Connection 2: encountered error(1:53) 2021-12-07 06:02:20.153125+0700 App[654:65556] Connection 2: received failure notification 2021-12-07 06:02:20.153280+0700 App[654:65556] [connection] nw_connection_copy_connected_local_endpoint [C2] Connection has no connected path 2021-12-07 06:02:20.153891+0700 App[654:65556] [connection] nw_connection_copy_connected_remote_endpoint [C2] Connection has no connected path 2021-12-07 06:02:20.155082+0700 App[654:65556] Connection 3: encountered error(1:53) 2021-12-07 06:02:20.155293+0700 App[654:65556] Connection 3: received failure notification 2021-12-07 06:02:20.161795+0700 App[654:65556] [connection] nw_connection_copy_connected_local_endpoint [C3] Connection has no connected path 2021-12-07 06:02:20.161877+0700 App[654:65556] [connection] nw_connection_copy_connected_remote_endpoint [C3] Connection has no connected path 🦴 Successfully fetched Elmer's friends! ... Maybe Amplify doesn't work when in the background? I dunno. One thing that I have yet to try is testing with a simple, single API operation in lieu of the somewhat more involved getUpdateAppData() function that is currently running through completion. Any further thoughts and/or advice is appreciated. private func configureBackgroundTasks() { Logger.log(.info, "Registering background tasks...") let bgTaskIdentifier = "com.example.task" BGTaskScheduler.shared.register(forTaskWithIdentifier: bgTaskIdentifier, using: DispatchQueue.main) { (task) in Logger.log(.info, "Performing background task \(bgTaskIdentifier)") Task { if let updatedData = await appManager.getUpdateAppData() { DispatchQueue.main.async { appManager.data = updatedData task.setTaskCompleted(success: true) } } else { task.setTaskCompleted(success: false) } backgroundTaskManager.scheduleAppRefresh() } } }
Topic: App & System Services SubTopic: Core OS Tags:
Replies
Boosts
Views
Activity
Dec ’21
Reply to Run async tasks using Background Tasks
Hi @OOPer, Thanks much for taking the time to respond. I have tried several variations, in an attempt to get this working. The result from your suggested mods: using Task instead of Task.init and putting task.setTaskCompleted(success: true) in a DispatchQueue.main.async {}, results in: 2021-12-04 14:58:39.136393-0800 App[8341:2562502] [connection] nw_read_request_report [C7] Receive failed with error "Socket is not connected" 2021-12-04 14:58:39.139668-0800 App[8341:2562502] [connection] nw_read_request_report [C7] Receive failed with error "Socket is not connected" Doing the same, but using Task.init {... results in: 2021-12-04 15:03:53.128265-0800 App[8344:2563988] [Framework] Task <BGAppRefreshTask: com.example.task> dealloc'd without completing. This is a programmer error. 2021-12-04 15:03:53.128610-0800 App[8344:2563988] Marking simulated task complete: (null) I do like the very specific calling out the programmer error 😄 I've also tried using BGProcessingTaskRequest instead of BGAppRefreshTaskRequest just in case the update operation was timing out after 30 seconds, which I believe is the time window alloted for a refresh task.
Topic: App & System Services SubTopic: Core OS Tags:
Replies
Boosts
Views
Activity
Dec ’21