We've been tracking an Alamofire issue for a while that involves a very rare crash in the URLSessionDataDelegate
method urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data)
, where the underlying NSData
is nil
when it's _unconditionallyBridgeFromObjectiveC
'd. Multiple Radars have been filed and I even spoke to an Apple engineer at WWDC '17 that said it was likely a rare bug where nil
is returned unintentionally. The fix seems easy enough to me (?: [NSData data]
) but we've gotten reports for iOS 10 and iOS 11 at least, so it wasn't fixed then. So the question becomes, how to work around it?
Well, surprisingly, marking the Data
parameter as Data?
actually works: urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data?)
. However, this leads to a warnings and perhaps unintentional compiler behavior: Parameter of 'urlSession(_:dataTask:didReceive:)' has different optionality than expected by protocol 'URLSessionDataDelegate'
. However, I don't think a permanent warning for all Alamofire users in acceptable here, especially since the vast majority have never seen this crash. So conditionalizing the fallback seems like the best option. However, Swift doesn't support the obvious version we'd want:
#if ENABLE_NIL_DATA_WORKAROUND
open func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data?) {
let data = data ?? Data()
#else
open func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
#endif
So before we do the work to create a version that works while minimizing duplication, does anyone have a better idea for a workaround? Additionally, is this fuzzy delegate matching behavior intentional, and will it remain?