Мутирующая функция внутри структуры - PullRequest
0 голосов
/ 11 мая 2018

Я использую Swift 4, у меня есть структура, которую я инициализирую значениями по умолчанию.Я сделал функцию внутри, которая должна читать JSON и изменять значения по умолчанию с тем, что он получает, но, похоже, он не работает.

Ошибка: Закрытие не может неявно захватить изменяющийся параметр self

Код:

struct Workspace: Decodable {
    var guid: String
    var name: String

private enum CodingKeys : String, CodingKey {
    case guid = "guid"
    case name = "name"
}

init(){
    self.guid = "blbl"
    self.name = "oops"
}

mutating func getUserWorkspace(base: String, completed: @escaping () -> ()){
    let url = URL(string: "some url")!
    var request = URLRequest(url: url)

    request.addValue("Basic \(base)", forHTTPHeaderField: "Authorization")
    request.addValue("application/json", forHTTPHeaderField: "Accept")

    URLSession.shared.dataTask(with: request){ (data, response, error) in
        if error == nil {
            do {
                let res: Workspace = try JSONDecoder().decode(Workspace.self, from: data!)
                self.guid = res.guid  //Error here
                self.name = res.name  //Error here
                DispatchQueue.main.async {
                    completed()
                }
            }catch {
                print ("JSON error")
            }
        }
    }.resume()
}

Я изменил let на var, но я думаю, что есть что-то, чего я не понимаю..

Ответы [ 3 ]

0 голосов
/ 11 мая 2018

Я бы предложил вам использовать class вместо struct. В любом случае, если вы хотите использовать свой код, захватите self внутри метода мутации, как показано ниже:

mutating func getUserWorkspace(base: String, completed: @escaping () -> ()){
        let url = URL(string: "some url")!
        var request = URLRequest(url: url)
        var myself = self

        request.addValue("Basic \(base)", forHTTPHeaderField: "Authorization")
        request.addValue("application/json", forHTTPHeaderField: "Accept")

        URLSession.shared.dataTask(with: request){ (data, response, error) in
            if error == nil {
                do {
                    let res: Workspace = try JSONDecoder().decode(Workspace.self, from: data!)
                    myself.guid = res.guid  //Error here
                    myself.name = res.name  //Error here
                    DispatchQueue.main.async {
                        completed()
                    }
                }catch {
                    print ("JSON error")
                }
            }
            }.resume()
  }
0 голосов
/ 18 мая 2018

Я на самом деле обнаружил проблему ... и это было довольно глупо .. Мне просто нужно было изменить "завершенную" часть функции, например так:

 mutating func getUserWorkspace(base: String, completed: @escaping (_ arr:[Workspace]?) -> ()){
    let url = URL(string: "SOME URL")!
    var request = URLRequest(url: url)

    request.addValue("Basic \(base)", forHTTPHeaderField: "Authorization")
    request.addValue("application/json", forHTTPHeaderField: "Accept")

    URLSession.shared.dataTask(with: request){ (data, response, error) in
        if error == nil {
            do {
                let rep = try JSONDecoder().decode([Workspace].self, from: data!)
                DispatchQueue.main.async {
                    completed(rep)
                }
            }catch {
                print(error)
            }
        }
    }.resume()
}
0 голосов
/ 11 мая 2018
//Try this one and let me know
struct Workspace: Decodable {
    static var shared = Workspace()
    var guid: String
    var name: String

    private enum CodingKeys : String, CodingKey {
        case guid = "guid"
        case name = "name"
    }

    init(){
        self.guid = "blbl"
        self.name = "oops"
    }

    mutating func getUserWorkspace(base: String, completed: @escaping () -> ()){
        let url = URL(string: "some url")!
        var request = URLRequest(url: url)

        request.addValue("Basic \(base)", forHTTPHeaderField: "Authorization")
        request.addValue("application/json", forHTTPHeaderField: "Accept")

        URLSession.shared.dataTask(with: request){ (data, response, error) in
            if error == nil {
                do {
                    let res: Workspace = try JSONDecoder().decode(Workspace.self, from: data!)
                    Workspace.shared.guid = res.guid  //Error here
                    Workspace.shared.name = res.name  //Error here
                    DispatchQueue.main.async {
                        completed()
                    }
                }catch {
                    print ("JSON error")
                }
            }
            }.resume()
    }
}
...