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 Deep link to Apple Music library playlist from Swift (iOS) app
It turns out you can open Apple Music to the user's library, using /library/ in the path, but it seems that's as deep as it will link. This works let urlString = "music://music.apple.com/library"                                         if let url = URL(string: urlString) {                                             await UIApplication.shared.open(url)                                         } This opens Apple Music to the user's library. This doesn't let urlString = "music://music.apple.com/library/playlists"                                         if let url = URL(string: urlString) {                                             await UIApplication.shared.open(url)                                         } This doesn't let urlString = "music://music.apple.com/library/playlist/\(playlistID)"                                         if let url = URL(string: urlString) {                                             await UIApplication.shared.open(url)                                         } The above two open Apple Music, which then displays an error: "An Error Occurred" with a Try Again button
Topic: Media Technologies SubTopic: General Tags:
Oct ’21
Reply to iOS 15 App Stops immediately after launch screen when using ipa
Okay, I tracked this down to an environment variable that was being used by the "dev" (i.e. debug) environment. As environment variables are not available in "production" (i.e. release), this one particular variable was causing the app to just stop. There was no message in the console log that reflected this that I could see, though there were guards that threw fatally if the environment variable was not present. Anyhow, once this was moved to a .plist and called from there, the app loaded as expected in both dev and prod.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Oct ’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
Reply to Get listing of public playlists for any Apple Music user Swift iOS
@JoeKun any thoughts on this?
Topic: Media Technologies SubTopic: General Tags:
Replies
Boosts
Views
Activity
Nov ’21
Reply to Deep link to Apple Music library playlist from Swift (iOS) app
It turns out you can open Apple Music to the user's library, using /library/ in the path, but it seems that's as deep as it will link. This works let urlString = "music://music.apple.com/library"                                         if let url = URL(string: urlString) {                                             await UIApplication.shared.open(url)                                         } This opens Apple Music to the user's library. This doesn't let urlString = "music://music.apple.com/library/playlists"                                         if let url = URL(string: urlString) {                                             await UIApplication.shared.open(url)                                         } This doesn't let urlString = "music://music.apple.com/library/playlist/\(playlistID)"                                         if let url = URL(string: urlString) {                                             await UIApplication.shared.open(url)                                         } The above two open Apple Music, which then displays an error: "An Error Occurred" with a Try Again button
Topic: Media Technologies SubTopic: General Tags:
Replies
Boosts
Views
Activity
Oct ’21
Reply to iOS 15 App Stops immediately after launch screen when using ipa
Okay, I tracked this down to an environment variable that was being used by the "dev" (i.e. debug) environment. As environment variables are not available in "production" (i.e. release), this one particular variable was causing the app to just stop. There was no message in the console log that reflected this that I could see, though there were guards that threw fatally if the environment variable was not present. Anyhow, once this was moved to a .plist and called from there, the app loaded as expected in both dev and prod.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Oct ’21