Назначьте значение для члена класса в функции - PullRequest
0 голосов
/ 21 февраля 2019

У меня есть класс, который имеет две переменные-члены и функцию.Функция вызывается, когда пользователь переходит на новую раскадровку и использует запрос HTTP GET с переменной-членом y, чтобы присвоить значение переменной-члену x.После завершения функции я пытаюсь присвоить x новой переменной раскадровки, но это ноль.Как мне присвоить значение x внутри функции, а затем передать x в новую раскадровку?

import UIKit
import os.log

class testViewController: UIViewController {

    var x: XClass!
    var y = “1234”

    override func viewDidLoad() {
        super.viewDidLoad()  
    }

    // MARK: - Navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        super.prepare(for: segue, sender: sender)

        switch(segue.identifier ?? "") {
        case “ZViewController”:
            guard let zviewcontroller = segue.destination as? ZViewController else{
                fatalError("Unexpected Destination: \(segue.destination)")
            }

            loadXDetail()
            zviewcontroller.x = x


        default:
            os_log("Not ZViewController Segue", log: OSLog.default, type: .debug)
        }
    }

    private func loadX(){
        // credentials encoded in base64
        let username = “***”
        let password = “***”
        let loginData = String(format: "%@:%@", username, password).data(using: String.Encoding.utf8)!
        let base64LoginData = loginData.base64EncodedString()

        // create the request
        let url = URL(string: "https://example.com")!
        var request = URLRequest(url: url)
        request.httpMethod = "GET"
        request.setValue("Basic \(base64LoginData)", forHTTPHeaderField: "Authorization")

        //making the request
        let task = URLSession.shared.dataTask(with: request) { data, response, error in
            guard let data = data, error == nil else {
                print("\(error)")
                return
            }

            if let httpStatus = response as? HTTPURLResponse {
                // check status code returned by the http server
                print("status code = \(httpStatus.statusCode)")
                do {
                    let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String:Any]
                    let items = json["items"] as? [[String: Any]] ?? []
                    for dic in items{
                        //guard let api = dic["Type"] as? String else {return}
                        let a = dic[“A”] as! String
                        let b = dic[“B”] as! String
                        let c = dic[“C”] as! String

                        self.x = XClass(y: y, a: a, b: b, c: c)!
                    }
                } catch let error as NSError {
                    print(error)
                    return
                }
            }
        }
        task.resume()
    }
}

Ответы [ 2 ]

0 голосов
/ 21 февраля 2019

swift 4.2 / Xcode 10.1:

Существует несколько способов передачи данных между viewControllers или классами.

Самый простой способ - использовать глобальную переменную.Например:

import UIKit

var myGlobalVariable = ""  //Or any Type you need

class testViewController: UIViewController {

private func loadX(){

//Do some stuff ...

myGlobalVariable = x

}

import UIKit

class ZViewController: UIViewController {

override func viewDidLoad() {

print(myGlobalVariable)

}

Или, используя шаблон синглтона.Например:

Создать класс, например:

import Foundation

class  SetVariable {

    var test: String?  //Or any type you need

    private init () {}

    static let shared = SetVariable.init()
}

class testViewController: UIViewController {

private func loadX(){

//Do some stuff ...

SetVariable.shared.test = x

}

class ZViewController: UIViewController {

override func viewDidLoad() {

print(SetVariable.shared.test)

}
0 голосов
/ 21 февраля 2019

Вы не можете предотвратить переход внутри prepare(for segue до тех пор, пока ваш запрос не завершится, вам нужно начать вызов асинхронного метода, когда вам нужно перейти по

loadX()

, а затем по завершении let task = URLSession.shared.dataTask(with: request) do

 self.x = XClass(y: y, a: a, b: b, c: c)!
 }
 DispatchQueue.main.async {
    self.performSegue(withIdentifier:"SegueID",sender:nil)
 }

и в этот момент x var имеет правильное значение в соответствии с ответом


другая вещь, вам может понадобиться x как любой массив, так как он будет содержать последнийзначение из этого цикла

                for dic in items{
                    //guard let api = dic["Type"] as? String else {return}
                    let a = dic[“A”] as! String
                    let b = dic[“B”] as! String
                    let c = dic[“C”] as! String

                    self.x = XClass(y: y, a: a, b: b, c: c)!
                }

плюс рассмотрите возможность использования Codable для декодирования вашего ответа вместо JSONSerialization

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...