Skip to content

Commit 104b09f

Browse files
committed
Fix async remote image loading, add logs
1 parent 14cb513 commit 104b09f

File tree

1 file changed

+74
-6
lines changed

1 file changed

+74
-6
lines changed

ios/Classes/Utils/ImageParser.swift

Lines changed: 74 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,84 @@ func getImageByName(_ name: String) -> UIImage? {
55
return img
66
}
77
if let path = Bundle.main.path(forResource: SwiftArkitPlugin.registrar!.lookupKey(forAsset: name), ofType: nil) {
8-
return UIImage(named: path)
8+
let img = UIImage(named: path)
9+
if img == nil {
10+
debugPrint("getImageByName: failed to load asset image at path \(path) for \(name)")
11+
}
12+
return img
913
}
1014
if let url = URL(string: name) {
11-
do {
12-
let data = try Data(contentsOf: url)
13-
return UIImage(data: data)
14-
} catch {}
15+
let (data, response, error) = fetchUrlData(url)
16+
if let http = response as? HTTPURLResponse, !(200...299).contains(http.statusCode) {
17+
let httpURLString = http.url?.absoluteString ?? ""
18+
debugPrint("getImageByName: network non-2xx status \(http.statusCode) url \(httpURLString)")
19+
}
20+
21+
if let error = error {
22+
let nsError = error as NSError
23+
debugPrint(
24+
"getImageByName: network load failed for \(name) (\(url)) " +
25+
"error: \(nsError.localizedDescription) " +
26+
"domain: \(nsError.domain) code: \(nsError.code) " +
27+
"userInfo: \(nsError.userInfo)"
28+
)
29+
return nil
30+
}
31+
32+
guard let data = data else {
33+
debugPrint("getImageByName: network returned no data for \(name)")
34+
return nil
35+
}
36+
37+
let img = UIImage(data: data)
38+
if img == nil {
39+
debugPrint("getImageByName: network data not decodable as image for \(name) (bytes: \(data.count))")
40+
}
41+
return img
1542
}
1643
if let base64 = Data(base64Encoded: name, options: .ignoreUnknownCharacters) {
17-
return UIImage(data: base64)
44+
let img = UIImage(data: base64)
45+
if img == nil {
46+
debugPrint("getImageByName: base64 data not decodable as image (bytes: \(base64.count))")
47+
}
48+
return img
1849
}
50+
debugPrint("getImageByName: failed to resolve image for \(name)")
1951
return nil
2052
}
53+
54+
private func fetchUrlData(_ url: URL) -> (Data?, URLResponse?, Error?) {
55+
let sessionConfig = URLSessionConfiguration.ephemeral
56+
sessionConfig.timeoutIntervalForRequest = 15
57+
sessionConfig.timeoutIntervalForResource = 20
58+
59+
let session = URLSession(configuration: sessionConfig)
60+
var request = URLRequest(url: url)
61+
request.cachePolicy = .reloadIgnoringLocalCacheData
62+
request.setValue("Mozilla/5.0", forHTTPHeaderField: "User-Agent")
63+
64+
let semaphore = DispatchSemaphore(value: 0)
65+
var resultData: Data?
66+
var resultResponse: URLResponse?
67+
var resultError: Error?
68+
69+
let task = session.dataTask(with: request) { data, response, error in
70+
resultData = data
71+
resultResponse = response
72+
resultError = error
73+
semaphore.signal()
74+
}
75+
task.resume()
76+
77+
let waitResult = semaphore.wait(timeout: .now() + 20)
78+
if waitResult == .timedOut {
79+
let timeoutError = NSError(
80+
domain: NSURLErrorDomain,
81+
code: NSURLErrorTimedOut,
82+
userInfo: [NSLocalizedDescriptionKey: "URLSession timed out"]
83+
)
84+
return (nil, nil, timeoutError)
85+
}
86+
87+
return (resultData, resultResponse, resultError)
88+
}

0 commit comments

Comments
 (0)