Swift 3 版本:
func isUpdateAvailable() throws -> Bool {
guard let info = Bundle.main.infoDictionary,
let currentVersion = info["CFBundleShortVersionString"] as? String,
let identifier = info["CFBundleIdentifier"] as? String,
let url = URL(string: "http://itunes.apple.com/lookup?bundleId=\(identifier)") else {
throw VersionError.invalidBundleInfo
}
let data = try Data(contentsOf: url)
guard let json = try JSONSerialization.jsonObject(with: data, options: [.allowFragments]) as? [String: Any] else {
throw VersionError.invalidResponse
}
if let result = (json["results"] as? [Any])?.first as? [String: Any], let version = result["version"] as? String {
return version != currentVersion
}
throw VersionError.invalidResponse
}
我认为抛出错误而不是返回 false 更好,在这种情况下我创建了一个 VersionError 但它可以是你定义的其他错误或 NSError
enum VersionError: Error {
case invalidResponse, invalidBundleInfo
}
也可以考虑从另一个线程调用这个函数,如果连接速度很慢会阻塞当前线程。
DispatchQueue.global().async {
do {
let update = try self.isUpdateAvailable()
DispatchQueue.main.async {
// show alert
}
} catch {
print(error)
}
}
更新
使用 URLSession:
我们可以使用URLSession,而不是使用Data(contentsOf: url) 并阻塞线程:
func isUpdateAvailable(completion: @escaping (Bool?, Error?) -> Void) throws -> URLSessionDataTask {
guard let info = Bundle.main.infoDictionary,
let currentVersion = info["CFBundleShortVersionString"] as? String,
let identifier = info["CFBundleIdentifier"] as? String,
let url = URL(string: "http://itunes.apple.com/lookup?bundleId=\(identifier)") else {
throw VersionError.invalidBundleInfo
}
Log.debug(currentVersion)
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
do {
if let error = error { throw error }
guard let data = data else { throw VersionError.invalidResponse }
let json = try JSONSerialization.jsonObject(with: data, options: [.allowFragments]) as? [String: Any]
guard let result = (json?["results"] as? [Any])?.first as? [String: Any], let version = result["version"] as? String else {
throw VersionError.invalidResponse
}
completion(version != currentVersion, nil)
} catch {
completion(nil, error)
}
}
task.resume()
return task
}
示例:
_ = try? isUpdateAvailable { (update, error) in
if let error = error {
print(error)
} else if let update = update {
print(update)
}
}