Разбор локального файла JSON в UICollectionView - PullRequest
3 голосов
/ 30 апреля 2019

Отказ от ответственности - я новичок в разработке Swift / IOS

Следуя этому руководству, я смог получить / отобразить локальный файл JSON (фактически файл .txt), выполнивследующее:

guard let path = Bundle.main.path(forResource: "test", ofType: "txt") else { return cell }
let url = URL(fileURLWithPath: path)

do{
    let data = try Data(contentsOf: url)
    let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers)

    guard let array = json as? [Any] else {return cell}

    for user in array {
        guard let userDict = user as? [String: Any] else  { return cell }
        guard let mName = userDict["name"] as? String else { return cell }
        print(mName)
    }

}catch{
    print(error)
}

Это работает нормально, распечатывает все имена в моем файле.


Далее я хотел бы заполнить эти данные в UICollectionView.Итак, я следовал этому учебнику.Но в этом уроке он извлекает данные JSON из API / ссылки, как показано ниже:

import UIKit

typealias JSON = [String: Any]

class NetworkingService {

    static let shared = NetworkingService()
    private init() {}

    let session = URLSession.shared

    func getImgurs(success successBlock: @escaping (GetImgursResponse) -> Void) {
        guard let url = URL(string: "https://api.imgur.com/3/gallery/r/dogs") else { return }
        var request = URLRequest(url: url)
        request.addValue("Client-ID 40dfbed2b6935ec", forHTTPHeaderField: "authorization")

        session.dataTask(with: request) { (data, _, _) in
            guard let data = data else { return }
            do {
                guard let json = try JSONSerialization.jsonObject(with: data, options: []) as? JSON else { return }
                print(json)
                let getImgursResponse = try GetImgursResponse(json: json)
                DispatchQueue.main.async {
                    successBlock(getImgursResponse)
                }
            } catch {}
        }.resume()
    }

    func downloadImage(fromLink link: String, success successBlock: @escaping (UIImage) -> Void) {
        guard let url = URL(string: link) else { return }
        session.dataTask(with: url) { (data, _, _) in
            guard let data = data,
                let image = UIImage(data: data)
                else { return }
            DispatchQueue.main.async {
                successBlock(image)
            }
        }.resume()
    }
}

Сначала я попытался использовать ту же логику, что и в первом уроке, изменив URL, как показано ниже:

import UIKit

typealias JSON = [String: Any]

class NetworkingService {

    static let shared = NetworkingService()
    private init() {}

    let session = URLSession.shared

    func getImgurs(success successBlock: @escaping (GetImgursResponse) -> Void) {
        //Changing the URL to local path
        guard let path = Bundle.main.path(forResource: "test", ofType: "txt") else { return }
        let url = URL(fileURLWithPath: path)            

        var request = URLRequest(url: url)
        request.addValue("Client-ID 40dfbed2b6935ec", forHTTPHeaderField: "authorization")

        session.dataTask(with: request) { (data, _, _) in
            guard let data = data else { return }
            do {
                guard let json = try JSONSerialization.jsonObject(with: data, options: []) as? JSON else { return }
                print(json)
                let getImgursResponse = try GetImgursResponse(json: json)
                DispatchQueue.main.async {
                    successBlock(getImgursResponse)
                }
            } catch {}
        }.resume()
    }

    func downloadImage(fromLink link: String, success successBlock: @escaping (UIImage) -> Void) {
        guard let url = URL(string: link) else { return }
        session.dataTask(with: url) { (data, _, _) in
            guard let data = data,
                let image = UIImage(data: data)
                else { return }
            DispatchQueue.main.async {
                successBlock(image)
            }
        }.resume()
    }
}

Но затем он возвращается на guard let json = try JSONSerialization.jsonObject(with: data, options: []) as? JSON else { return }

Может кто-нибудь дать мне совет, как мне этого добиться?

Ответы [ 2 ]

1 голос
/ 30 апреля 2019

Вы можете использовать следующую функцию для заполнения локальных данных JSON в UICollectionView

func getUsersList() -> [Any]{
    guard let path = Bundle.main.path(forResource: "test", ofType: "txt") else { return [] }
    let url = URL(fileURLWithPath: path)

    do{
        let data = try Data(contentsOf: url)
        let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers)

        guard let array = json as? [Any] else {return []}

        return array;

    }catch{
        print(error)
        return []
    }
}

После получения списка из функции, затем перезагрузите коллекцию с таким же массивом, как этот:

var arrUsersLists : [Any] = []

override func viewDidLoad() {
    super.viewDidLoad()

    self.arrUsersLists = self.getUsersList()
    self.collectionView.reloadData()
}
0 голосов
/ 30 апреля 2019
do{
    if let jsonObject: AnyObject = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as? [String: AnyObject] as AnyObject? {

        if let dict = jsonObject as? NSDictionary {
            if isDebuging {
                print(dict)
            }


        } else {
            print("not a dictionary")
        }
    }
    else {

        if isDebuging {
            print("Could not parse JSON: \(error!)")
        }


    }
}catch let  error as NSError {
    print(error.localizedDescription)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...