我是iOS开发的初学者.我试图在我的求职iOS应用程序中使用一个api URl:https://www.arbeitnow.com/api/job-board-api.但我的应用程序上什么都没显示.我在POSTMAN中测试了URL,它返回json(但在描述部分返回HTML?).我写了代码:

func getResults(completed: @escaping (Result<[Results], ErrorMessage>) -> Void) { 
    let urlString = "https://www.arbeitnow.com/api/job-board-api"
    guard let url = URL(string: urlString) else {return}    
    let task = URLSession.shared.dataTask(with: url) { data, response, error in    
        if let _ = error {
            completed(.failure(.invalidData))
            return
        }   
        guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {
            completed(.failure(.invalidResponse))
            return
        }
        guard let data = data else {
            completed(.failure(.invalidData))
            return
        } 
        do {
            let deconder = JSONDecoder()
            deconder.keyDecodingStrategy = .convertFromSnakeCase
            let results = try deconder.decode([Results].self, from: data)
            completed(.success(results))     
        } catch {
            completed(.failure(.invalidData))
        }
    }
    task.resume()
}

struct Results: Codable {
    let slug, companyName, title, resultsDescription: String
    let remote: Bool
    let url: String
    let tags, jobTypes: [String]
    let location: String
    let createdAt: Int
    enum CodingKeys: String, CodingKey {
        case slug
        case companyName = "company_name"
        case title
        case resultsDescription = "description"
        case remote, url, tags
        case jobTypes = "job_types"
        case location
        case createdAt = "created_at"
    }
}

我在HomeViewController中使用了以下代码:

override func viewDidLoad() {
    super.viewDidLoad()
    title = "Home"
    collectionView.backgroundColor = UIColor(named: "backgroundMain")
    collectionView.register(SearchViewCell.self, forCellWithReuseIdentifier: cellId)
    setupSearchBar()
    Service.shared.getResults() { [weak self] result in
        switch result {
        case .success(let results):
            print(results)
            self?.jobResults = results
            DispatchQueue.main.async {
                self?.collectionView.reloadData()
            }   
        case .failure(let error):
            print(error)
        }
    }
}

888

我不知道我的代码出了什么问题.有人能帮忙吗?谢谢

推荐答案

您正在丢弃所有有意义的错误信息,这将使诊断变得困难.如果得到Error个对象,则应返回:

enum WebServiceError: Error {
    case httpError(Data, Int)
}

func getResults(completion: @escaping (Result<[Results], Error>) -> Void) {
    let urlString = "https://www.arbeitnow.com/api/job-board-api"
    guard let url = URL(string: urlString) else {
        completion(.failure(URLError(.badURL)))
        return
    }

    let task = URLSession.shared.dataTask(with: url) { data, response, error in
        guard
            let data = data,
            let response = response as? HTTPURLResponse,
            error == nil
        else {
            completion(.failure(error ?? URLError(.badServerResponse)))
            return
        }

        guard 200 ..< 300 ~= response.statusCode else {
            completion(.failure(WebServiceError.httpError(data, response.statusCode)))
            return
        }

        do {
            let decoder = JSONDecoder()
            decoder.keyDecodingStrategy = .convertFromSnakeCase
            let results = try decoder.decode([Results].self, from: data)
            completion(.success(results.data))
        } catch {
            completion(.failure(error))
        }
    }
    task.resume()
}

所以,这将,

  • 如果有URLSession个错误,告诉你错误是什么;
  • 如果有一个非2xx状态代码,告诉你代码是什么(如果你想查看,也返回响应的主体);和
  • 如果有解析错误,请告诉您解析错误是什么.

如果没有这样的东西,捕捉到显著的错误信息,你就是在瞎飞.


在本例中,错误在于您正在解析[Results],但 struct 是一个字典,其键是data,其值是[Results].您缺少一个包含[Results]的字典对象.

struct ResponseObject: Decodable {
    let data: [Posting]
    let links: Links
    let meta: Meta
}

struct Posting: Decodable {
    let slug, companyName, title, description: String
    let remote: Bool
    let url: String
    let tags, jobTypes: [String]
    let location: String
    let createdAt: Int
}

struct Links: Decodable {
    let first: URL?
    let last: URL?
    let prev: URL?
    let next: URL?
}

struct Meta: Decodable {
    let currentPage: Int
    let path: URL
    let perPage: Int
    let from: Int
    let to: Int
    let terms: String
    let info: String
}

func getResults(completion: @escaping (Result<[Posting], Error>) -> Void) {
    let urlString = "https://www.arbeitnow.com/api/job-board-api"
    guard let url = URL(string: urlString) else {
        completion(.failure(URLError(.badURL)))
        return
    }

    let task = URLSession.shared.dataTask(with: url) { data, response, error in
        guard
            let data = data,
            let response = response as? HTTPURLResponse,
            error == nil
        else {
            completion(.failure(error ?? URLError(.badServerResponse)))
            return
        }

        guard 200 ..< 300 ~= response.statusCode else {
            completion(.failure(WebServiceError.httpError(data, response.statusCode)))
            return
        }

        do {
            let decoder = JSONDecoder()
            decoder.keyDecodingStrategy = .convertFromSnakeCase
            let results = try decoder.decode(ResponseObject.self, from: data)
            completion(.success(results.data))
        } catch {
            completion(.failure(error))
        }
    }
    task.resume()
}

Ios相关问答推荐

React Native Text组件内部TextInput组件在iOS上的问题:在TextInput组件内部键入文本时失go 焦点

滚动时突出显示工具栏项目

如何在wiftUI中管理导航栈?

IFrame内容拒绝仅在iOS浏览器上加载-即使发布了内容-安全-策略(CSP)框架-祖先指令

如何从Windows PC在iPhone上安装Flutter 应用程序

如何防止UITest套件与Fastlane一起执行?

如何删除NavigationView中的默认透明标头?

如何在应用程序中显示我的小部件的快照?

如何解码没有名称的 JSON 数组?

在 iPad 上删除列表的顶部和底部行

如何让我的 iOS 应用程序与 api 连接?

如何获取 UICollectionViewCell 的矩形?

是否可以在没有 Mac 的情况下为 iOS 制作 PhoneGap 应用程序?

Xcode 4.1 致命错误:自构建预编译头文件后修改了 stdlib

从 NSData 或 UIImage 中查找图像类型

UIView 动画与 CALayers

如何在上传到服务器之前在 iOS 上压缩/调整图像大小?

如何隐藏uitabbar控制器

如何使用 Contacts Framework 获取 iOS 9 中的所有联系人记录

在 iOS 上没有显示数字键盘