Как передать данные из одного viewcontroller в другой viewcontroller, который получен в json и должен быть установлен в табличном представлении? - PullRequest
0 голосов
/ 12 декабря 2018

Вот мой код:

public func getMethod() -> Array<Any>{
    var array = [Any]()
    let session = URLSession.shared
    let aURL = URL(string: baseUrl+month)!
    var request = URLRequest(url: aURL)
    request.setValue("application/json", forHTTPHeaderField: "Accept")
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.setValue("Bearer \(UserDefaults.standard.string(forKey: Actoken)!)", forHTTPHeaderField: "Authorization")
    let task = session.dataTask(with: request, completionHandler: {(data, response, error) in
        do {
            let json = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.allowFragments)
            array = [json]
            print(array)
            print(json)
        } catch {
            print("Could not serialise")
        }

    })
    print(array)
    task.resume()

    return array
}

Результат, который я получаю из JSON:

{
    {
        item = 1,
        name = "Abc"
    },
    {
        item = 1,
        name = "Def"
    }
}

Но когда я пытаюсь вернуться в другой контроллер представления, он возвращает нулевое значение.Если не таким образом, как я могу продолжить.Мне нужно вставить производный JSON в табличное представление.

Ответы [ 3 ]

0 голосов
/ 12 декабря 2018

Передайте замыкание в getMethod, которое будет выполнено при получении ответа.Внутри замыкания обновите источник данных tableview с помощью json и reloadData.

public func getMethod(completion: (yourCustomType)->() ) {

    ...

    let task = session.dataTask(with: request, 
                   completionHandler: {(data, response, error) in

        if let data = data {
            do {
                let json = try JSONDecoder.decode(yourCustomType.self, data)
                completion(json)
            }catch {
                    ...
            }
        }

   })

   task.resume()
}

getMethod() { (responseData: YourCustomType) in
    tableviewDatasource = responseData
    DispatchQueue.main.async{ 
        self.tableview.reloadData
    }
}
0 голосов
/ 12 декабря 2018

Это не так, как работает асинхронное программирование.

Вы делаете асинхронный вызов (вызов session.dataTask) и ожидаете синхронного возврата результатов.Ваша вызывающая функция считывает результат, вероятно, до завершения сетевого вызова.Вместо этого вы должны использовать замыкание (блок завершения).

Вот простой код игровой площадки, демонстрирующий асинхронную модель:

import UIKit
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

let Actoken = "SOMETHING"

public func getMethod(baseUrl:String, month:String, completion:@escaping (Array<Any>?)->()){

    var array = [Any]()
    let session = URLSession.shared
    guard let aURL = URL(string: baseUrl+month) else {
        print("invalid url")
        completion(nil)
        return
    }
    var request = URLRequest(url: aURL)
    request.setValue("application/json", forHTTPHeaderField: "Accept")
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    let task = session.dataTask(with: request, completionHandler: {(data, response, error) in
        do {
            if let data = data {
                let json = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments)
                array = [json]
                completion(array)
            } else {
                completion(nil)
            }
        }
        catch {
            print("Could not serialise")
            completion(nil)
        }
    })
    task.resume()
}

// here's how you call it from the view controller
getMethod(baseUrl: "https://mobilesecurity.win/sample.json", month: "") { array in
    if let array = array {
        print(array)
    } else {
        print("array was nil")
    }
}
0 голосов
/ 12 декабря 2018

Вы должны использовать completion для любой асинхронной операции, поэтому ваш код должен выглядеть следующим образом:

class classA {

public func getMethod(completion: @escaping (_ resultArray: [Any])->()) {
        var array = [Any]()
        let session = URLSession.shared
        let aURL = URL(string: baseUrl+month)!
        var request = URLRequest(url: aURL)
        request.setValue("application/json", forHTTPHeaderField: "Accept")
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.setValue("Bearer \(UserDefaults.standard.string(forKey: Actoken)!)", forHTTPHeaderField: "Authorization")
        let task = session.dataTask(with: request, completionHandler: {(data, response, error) in
            do {
                let json = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.allowFragments)
                array = [json]
                completion(array)
            }
            catch {
                print("Could not serialise")
            }
        })
        task.resume()
    }
}

// Вызывающий объект должен быть похож на

let yourClass = classA()
yourClass.getMethod { [weak self] (resultArr) in
    DispatchQueue.main.async {
        let classB = ClassB()
        classB.resultArray = resultArr
        self?.navigationController.pushViewController(classB, animated: true)
        }
    }

, как только он будет передан в класс Bс помощью массива результатов вы можете проанализировать ответ JSON и заполнить таблицу.

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