簡體   English   中英

如何使用Alamofire和SwiftyJSON從Json保存數據?

[英]How to save data from Json with Alamofire and SwiftyJSON?

我試圖用這兩個庫將“作者”數據保存到json(鏈接:“ https://learnappmaking.com/ex/books.json ”)中名為“authors”的全局變量中。 但它只適用於func Alamofire.request(url).responseJSON的尾隨關閉。 當我從除了尾隨閉包之外的某個地方訪問名為“authors”的全局變量時,我得到的是一個空字符串數組。

有人可以解釋這種情況背后的原因嗎?非常感謝。

class ViewController: UIViewController {

    var authors = [String]()
    let url = "https://learnappmaking.com/ex/books.json"


    func getAuthorsCount() {
        print("the number of authors : \(authors.count)") // I hope that here, the number of authors should be 3 too! actually, it is 0. Why? 

        // this for loop doesn't get excuted
        for author in authors {
            print(author)
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        Alamofire.request(url).responseJSON { response in
            if let data = response.data {
                if let json = try? JSON(data: data) {
                    for item in json["books"].arrayValue {
                        var outputString: String
                        print(item["author"])
                        outputString = item["author"].stringValue
                        //urlOfProjectAsset.append(outputString)
                        self.authors.append(outputString)
                        print("authors.count: \(self.authors.count)")
                    }
                }
            }
    }

        getAuthorsCount()
        print("-------------")
    }
}

實際輸出是:

在此輸入圖像描述


更新 :我調整了我的代碼:

class ViewController: UIViewController {

    var authors = [String]()
    let url = "https://learnappmaking.com/ex/books.json"


    func getAuthorsCount() {
        print("the number of authors : \(authors.count)")

        // this for loop doesn't get excuted
        for author in authors {
            print(author)
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        Alamofire.request(url).responseJSON { response in
            if let data = response.data {
                if let json = try? JSON(data: data) {
                    for item in json["books"].arrayValue {
                        var outputString: String
                        //print(item["author"])
                        outputString = item["author"].stringValue
                        //urlOfProjectAsset.append(outputString)
                        self.authors.append(outputString)
                        //print("authors.count: \(self.authors.count)")
                    }
                self.getAuthorsCount() // I added this line of code.
                }
            }
    }
        getAuthorsCount()
        print("-------------")
    }
}

但為什么func getAuthorsCount() (不是自我版本)仍然打印一個空數組的字符串? 我認為結果應該與func self.getAuthorsCount()打印的結果相同。 我現在很困惑...再次,我想使用保存在名為“authors”的變量中的數據,但我只得到一個空數組的字符串。

我會盡力回答你的所有問題:

  • 數據是持久的

  • 您正在執行以下操作:Alamo.request(網絡調用) - > getAuthors(打印結果 - 空) - >響應(接收響應) - > self.authors.append(保存響應) - > self.authors(打印結果)

  • 您需要這樣做:Alamo.request(網絡調用) - >響應(接收響應) - > self.authors.append(保存響應) - > self.getAuthors或getAuthors(相同)(在響應{}內)

在響應回調中,您需要在獲得結果后調用getAuthors:

override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        Alamofire.request(url).responseJSON { response in
            if let data = response.data {
                if let json = try? JSON(data: data) {
                    for item in json["books"].arrayValue {
                        var outputString: String
                        print(item["author"])
                        outputString = item["author"].stringValue
                        //urlOfProjectAsset.append(outputString)
                        self.authors.append(outputString)
                        print("authors.count: \(self.authors.count)")
                    }

                    self.getAuthorsCount()
                    print("-------------")
                   //Do whatever you want from here : present/push 


                }
            }
        }

然后你可以使用保存的數據:

  • 要將數據發送到另一個ViewController,您可以使用各種方法(present / push,closure / callback,...)
  • 通常你會有一個加載微調器等待網絡應答,然后你將顯示你的下一個控制器

根據直接消息的要求:一種僅限Swift的方法。 只需將其粘貼在空白的Playground中:

import Foundation

final class NetworkService {

  enum ServiceError: LocalizedError {
    case invalidUrl
    case networkingError(error: Error)
    case parsingError

    var localizedDescription: String? { return String(describing: self) }
  }


  func request(completion: @escaping (Result<[UserObject], Error>) -> Void ) {

    guard let url = URL(string: "https://jsonplaceholder.typicode.com/users") else {
      completion(.failure(ServiceError.invalidUrl))
      return
    }

    let dataTask = URLSession.shared.dataTask(with: url) { (jsonData, response, error) in
      if let jsonData = jsonData {
        let jsonDecoder = JSONDecoder()

        do {
          let users = try jsonDecoder.decode([UserObject].self, from: jsonData)
          completion(.success(users))
        } catch {
          completion(.failure(ServiceError.parsingError))
        }

      } else if let error = error {
        completion(.failure(ServiceError.networkingError(error: error)))
      }
    }
    dataTask.resume()

  }
}

struct UserObject: Codable {
  let id: Int
  let name: String
  let username: String
  let email: String?
  let website: String?
}


let networkService = NetworkService()
networkService.request { result in

  switch result {
  case .success(let users):
    debugPrint("Received \(users.count) users from REST API")
    debugPrint(users)
  case .failure(let error):
    debugPrint(error.localizedDescription)
  }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM