【问题标题】:How can i get authorization to retrieve data from API Swift?如何获得从 API Swift 检索数据的授权?
【发布时间】:2021-11-01 07:05:49
【问题描述】:

我正在尝试从 API 检索一些数据,但出现错误:“给定的数据不是有效的 JSON”,状态代码:401

我认为这是一个身份验证问题。如何设置身份验证凭据以发出 GET 请求?

这是从 JSON 中检索数据的代码。

    func loadData()
    {
    guard let url = URL(string: getUrl) else { return }
        
        URLSession.shared.dataTask(with: url) { data, res, err in
            do {
                if let data = data {
                    let result = try JSONDecoder().decode([ItemsModel].self, from: data)
                    DispatchQueue.main.async {
                        self.items = result
                    }
                    
                   
                } else {
                    print(" No Data ")
                }
            } catch( let error)
            {
                print(res)
                print(String(describing: error))
            }
        
            
            
        }.resume()
    }

这是视图的代码:

struct GetView: View {
    @ObservedObject var viewModel = ViewModel()
    
    var body: some View {
        NavigationView {
            VStack {
            List(viewModel.items, id: \.id) { item in
                Text(item.year)
            }
            } .onAppear(perform: {
                viewModel.loadData()
                    
            })

            .navigationTitle("Data")
        }
        
    }
}

【问题讨论】:

  • 在顶部的if let data = data 中打印String(data: data, encoding: .utf8)!。结果是什么?任何可读的JSON?将任何内容粘贴到问题中。
  • "如何设置身份验证凭据以发出 GET 请求?"你在说什么类型的授权?承载授权?基本授权?
  • 你好@George,这是我通过打印数据得到的结果“您没有此范围的访问权限”
  • @ElTomato 基本授权

标签: json swift api swiftui


【解决方案1】:

要处理身份验证,您必须为您的 URLSession 实现一个委托:

    func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        completionHandler(.performDefaultHandling, challenge.proposedCredential)
    }

但是,您的 401 错误可能是由于您的代码未向服务器发送有效的 GET 请求。您可能想要解码“res”值以确定状态码:

if let response = res as? HTTPURLResponse {
    if response.statusCode != 200 {
        // data may be JSON encoded but you should get some for
        // statusCode == 401
    }
}

在不知道您要连接的服务类型的情况下,很难推测您需要 GET 还是 POST。您使用的 URL 可能需要查询参数。

【讨论】:

    【解决方案2】:

    我找到了解决方案。这是基本身份验证的代码:

    func loadData() {
            
            //Credentials
            let username = ""
            let password = ""
            let loginString = "\(username):\(password)"
            let loginData = loginString.data(using: String.Encoding.utf8)!
            let base64LoginString = loginData.base64EncodedString()
            
            //Request
            guard let url = URL(string: getUrl) else {return}
            var request = URLRequest(url: url)
            request.httpMethod = "GET"
            request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization")
    
            //Setup Session
            let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
                do {
                    if let data = data {
                        print(String(data: data, encoding: .utf8)!)
                        let result = try JSONDecoder().decode([ItemsModel].self, from: data)
                        DispatchQueue.main.async {
                            self.items = result
                        }
                        
                       
                    }
                    
                    else {
                        print(" No Data ")
                    }
                } catch( let error)
                {
                   
                    print(String(describing: error))
                }
            
            
           
        }
            task.resume()
            
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-12
      • 1970-01-01
      • 1970-01-01
      • 2017-07-02
      • 2019-12-25
      • 1970-01-01
      • 2022-08-04
      • 1970-01-01
      相关资源
      最近更新 更多