在面向协议的网络代码的游乐场玩耍,在我把所有东西放在一起的最后一行,Xcode崩溃说
LLDB RPC服务器已崩溃......依此类推
我的代码中肯定存在一些严重错误,我确信这是在最后几行,但我无法弄明白。
import UIKit
import PlaygroundSupport
struct Repo {
let id: Int
let name: String
}
extension Repo {
init?(dict: JSONDict) {
guard let id = dict["id"] as? Int, let name = dict["name"] as? String else { return nil }
self.id = id
self.name = name
}
}
typealias JSONDict = [String:Any]
protocol Resource {
associatedtype Content
var url: URL { get }
func parse(data: Data) -> Content?
}
extension Resource {
func parseJSON(data: Data) -> Any? {
let json = try? JSONSerialization.jsonObject(with: data)
return json
}
}
struct RepoService: Resource {
let url = URL(string: "https://api.github.com/users/mkchoi212/repos")!
func parse(data: Data) -> [Repo]? {
guard let dictArray = self.parseJSON(data: data) as? [JSONDict] else { return nil }
return dictArray.flatMap(Repo.init)
}
}
final class WebService<Content> {
func load<R: Resource>(resource: R, completion: @escaping (R.Content?) -> ()) {
URLSession.shared.dataTask(with: resource.url) { data, _, _ in
let res = data.flatMap(resource.parse)
completion(res)
}.resume()
}
}
WebService().load(resource: RepoService) { res in
for elem in res {
print(elem)
}
}
PlaygroundPage.current.needsIndefiniteExecution = true
答案 0 :(得分:4)
崩溃的编译器是一个错误,应该报告。 Xcode 9(beta)没有 使用您的代码崩溃,但会提供有用的错误消息,从而产生解决方案:
error: generic parameter 'Content' could not be inferred WebService().load(resource: RepoService) { res in ^
Content
中的通用占位符class WebService<Content>
是
根本不使用,删除它并使该类非通用。然后:
error: generic parameter 'R' could not be inferred WebService().load(resource: RepoService) { res in ^
您必须将RepoService
的实例传递给load
方法,
闭包内的res
是可选的。
随着这些变化
final class WebService {
func load<R: Resource>(resource: R, completion: @escaping (R.Content?) -> ()) {
URLSession.shared.dataTask(with: resource.url) { data, _, _ in
let res = data.flatMap(resource.parse)
completion(res)
}.resume()
}
}
WebService().load(resource: RepoService()) { res in
guard let res = res else { return }
for elem in res {
print(elem)
}
}
您的代码在Xcode 8.3.3和9中编译并按预期运行。
答案 1 :(得分:0)
工作示例
import Foundation
import PlaygroundSupport
struct Repo {
let id: Int
let name: String
}
extension Repo {
init?(dict: JSONDict) {
guard let id = dict["id"] as? Int, let name = dict["name"] as? String else { return nil }
self.id = id
self.name = name
}
}
typealias JSONDict = [String:Any]
protocol Resource {
associatedtype Content
var url: URL { get }
func parse(data: Data) -> Content?
}
extension Resource {
func parseJSON(data: Data) -> Any? {
let json = try? JSONSerialization.jsonObject(with: data)
return json
}
}
struct RepoService: Resource {
let url = URL(string: "https://api.github.com/users/mkchoi212/repos")!
func parse(data: Data) -> [Repo]? {
guard let dictArray = self.parseJSON(data: data) as? [JSONDict] else { return nil }
return dictArray.flatMap(Repo.init)
}
}
final class WebService {
func load<R: Resource>(resource: R, completion: @escaping (R.Content) -> ()) {
URLSession.shared.dataTask(with: resource.url) { data, _, _ in
if let res = data.flatMap(resource.parse) {
completion(res)
}
}.resume()
}
}
WebService().load(resource: RepoService()) { res in
for elem in res {
print(elem)
}
}
PlaygroundPage.current.needsIndefiniteExecution = true
给了我这个结果
Repo(id: 93473150, name: "bitbuf")
Repo(id: 28517340, name: "DIJKASTRAS")
Repo(id: 71310619, name: "git-strbuf")
Repo(id: 30558002, name: "Habitats-master")
Repo(id: 28517464, name: "Home-Automation-Project")
Repo(id: 33394787, name: "hw.")
Repo(id: 39911528, name: "JPSThumbnailAnnotation")
Repo(id: 37162894, name: "M3")
Repo(id: 39709018, name: "Maroon")
Repo(id: 41267183, name: "mkchoi212.github.io")
Repo(id: 28519262, name: "Money-Saving-Meals")
Repo(id: 39857111, name: "MRCircularProgressView")
Repo(id: 81773538, name: "papers-we-love")
Repo(id: 37074317, name: "socket.io-client-swift")
Repo(id: 28519322, name: "Wordsneak")