Dispatch queue: com.apple.NSURLSession-delegate after executing self written shortcut

Currently I am trying to create some shortcuts for my iOS 17 app. The AppIntent looks like this:

class PostClass{
    
    public init() {

        let url = URL(string: "http://myurl")!
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        struct Message: Encodable {
            let device_type: String
        }
        let message = Message(
            device_type: "device"
        )
        let data = try! JSONEncoder().encode(message)
        request.httpBody = data
        request.setValue(
            "application/json",
            forHTTPHeaderField: "Content-Type"
        )
        self.request = request
    }
}

var activateDevice = PostClass()

@available(iOS 17, *)
struct ActivateIntent: AppIntent {
  static let title: LocalizedStringResource = "Activate"

  func perform() async throws -> some IntentResult {
      
      let task = URLSession.shared.dataTask(with: activateDevice.request) { data, response, error in
          let statusCode = (response as! HTTPURLResponse).statusCode
          
          if statusCode == 200 {
              print("SUCCESS")
          } else {
              print("FAILURE")
          }
      }
      task.resume()
    return .result()
  }
}

Unfortunately, the shortcut throws an error after every second execution. I looked into the ips-file and saw the following traceback:

Thread 2 Crashed:
0   Runner                        	       0x1028ddd30 closure #1 in ActivateIntent.perform() + 388
1   CFNetwork                     	       0x1a6f39248 0x1a6f2a000 + 62024
2   CFNetwork                     	       0x1a6f57210 0x1a6f2a000 + 184848
3   libdispatch.dylib             	       0x1adced13c _dispatch_call_block_and_release + 32
4   libdispatch.dylib             	       0x1adceedd4 _dispatch_client_callout + 20
5   libdispatch.dylib             	       0x1adcf6400 _dispatch_lane_serial_drain + 748
6   libdispatch.dylib             	       0x1adcf6f64 _dispatch_lane_invoke + 432
7   libdispatch.dylib             	       0x1add01cb4 _dispatch_root_queue_drain_deferred_wlh + 288
8   libdispatch.dylib             	       0x1add01528 _dispatch_workloop_worker_thread + 404
9   libsystem_pthread.dylib       	       0x201dd4f20 _pthread_wqthread + 288
10  libsystem_pthread.dylib       	       0x201dd4fc0 start_wqthread + 8

Is there any way to locate the error with these information? Has it something to do with the fact that my code is not thread-safe? Or is there any internal bug?

Grateful for any help, thanks in advance!

Replies

Please post a full crash report, per the advice in Posting a Crash Report.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Hi eskimo! Here's the full crash report

Thanks for the crash report. I spent a bunch of time looking at that, only to come back to something that you’d mentioned earlier O-:

Consider this code:

let task = URLSession.shared.dataTask(with: activateDevice.request) { data, response, error in
	let statusCode = (response as! HTTPURLResponse).statusCode
	…	
}

You’re almost certainly crashing due to a trap on that second line. That means that response is either nil or not an HTTPURLResponse. The former is much more likely.

In URLSession completion handlers there are two possible results:

  • error is not nil, indicating a transport error — This means that the system was unable to either send the request to the server or read the response back. In this case data and response will be nil.

  • error is not nil — This means that the request made it to the server and the response made it back. You then need to look at the response to see what the server made of your request. In this case data and response will be populated.

You’re ignoring error and unconditionally unwrapping response. If response is nil, you’ll trap.

The fix is to check error for nil and not crash in that case. The contents of that error will then help you decide as to how you should continue.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Hi eskimo, thanks a lot! It solved my problem!

A follow-up question: I managed to log the error and it says: "The request timed out." As I mentioned earlier, this only happens sometimes (it works in 2 out of 3 attempts). When I send the request via the console of my mac, it always works. Do you have any idea why it sometimes doesn't work via the AppIntent class?