Swift HTTP会话未发送实际请求

2024-10-01 04:51:12 发布

您现在位置:Python中文网/ 问答频道 /正文

所以我有一些Swift代码,可以向本地主机发送请求



//
//  ContentView.swift
//  Shared
//
//  Created by Ulto4 on 10/23/21.
//

import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack{
        Text("Hello, world!")
            .padding()
        Button(action : {
            self.fu()
        }, label: {
            Image(systemName: "pencil").resizable().aspectRatio(contentMode:.fit)
        })
    }
    }
    func fu(){
        let url = URL(string: "http://127.0.0.1:5000/232")

           

           guard let requestUrl = url else { fatalError() }



           
           var request = URLRequest(url: requestUrl)



         

           request.httpMethod = "GET"



      

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

               

              

               if let error = error {

                   print("Error took place \(error)")

                   return

               }

               

              

               if let response = response as? HTTPURLResponse {

                   print("Response HTTP Status code: \(response.statusCode)")

               }
            
        }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
   
        
    }

}


但是,在我的Flask应用程序中没有收到get请求,并且该函数没有运行。控制台上也没有任何打印内容。 我对斯威夫特相当陌生,所以我真的不知道如何解决这个问题。 是否有其他方法以swift发送请求,如果没有,我将如何解决此问题


Tags: viewurlifresponserequestvarerrorsome
1条回答
网友
1楼 · 发布于 2024-10-01 04:51:12

您正在创建URLSessionDataTask,但从未启动它。调用^{},例如

func performRequest() {
    guard let url = URL(string: "http://127.0.0.1:5000/232") else {
        fatalError()
    }

    let task = URLSession.shared.dataTask(with: url) { data, response, error in
        if let error = error {
            print("Error took place \(error)")
            return
        }

        if let response = response as? HTTPURLResponse {
            print("Response HTTP Status code: \(response.statusCode)")
        }
    }
    task.resume()           // you must call this to start the task
}

话虽如此,但有几点需要注意:

  1. 你在做http而不是https。确保使用应用程序传输设置临时启用不安全的网络请求,例如

    enter image description here

  2. 你没说这是针对macOS还是iOS的

    • 如果在物理iOS设备上运行,它将找不到127.0.0.1版本的macOS web服务器(即,它将找不到在iPhone上运行的web服务器)。您需要指定局域网上web服务器的IP号

    • 如果是macOS,请确保在目标的“功能”中启用出站网络请求:

      enter image description here


你问:

Is there any other way to send requests in swift?

这可能超出了你的问题范围,但更长远来说,当使用SWIFTUI时,你可以考虑使用{A4},例如^ {A5}。当运行一个简单的“what was the status code”(状态代码是什么)例程时,区别并不重要,但当您进入更复杂的场景,需要解析和处理响应时,Combine与SwiftUI的声明模式更为一致

让我们考虑一个更复杂的例子,您需要解析JSON响应。为了便于说明,下面我将使用httpbin.org进行测试,它将响应您发送的任何参数。我将演示^{}的使用,以及如何将其与函数链接模式一起使用,以摆脱繁琐的命令式代码的混乱:

struct SampleObject: Decodable {
    let value: String
}

struct HttpBinResponse<T: Decodable>: Decodable {
    let args: T
}

class RequestService: ObservableObject {
    var request: AnyCancellable?
    let decoder = JSONDecoder()
    @Published var status: String = "Not started yet"

    func startRequest() {
        request = createRequest().sink { completion in
            print("completed")
        } receiveValue: { [weak self] object in
            self?.status = "Received " + object.value
        }
    }

    func createRequest() -> AnyPublisher<SampleObject, Error>{
        var components = URLComponents(string: "https://httpbin.org/get")
        components?.queryItems = [URLQueryItem(name: "value", value: "foo")]

        guard let url = components?.url else {
            fatalError("Unable to build URL")
        }

        return URLSession.shared.dataTaskPublisher(for: url)
            .map(\.data)
            .decode(type: HttpBinResponse<SampleObject>.self, decoder: decoder)
            .map(\.args)
            .receive(on: DispatchQueue.main)
            .eraseToAnyPublisher()
    }
}

struct ContentView: View {
    @ObservedObject var requestService = RequestService()

    var body: some View {
        VStack{
            Text("Hello, world!")
                .padding()
            Button {
                requestService.startRequest()
            } label: {
                Image(systemName: "pencil").resizable().aspectRatio(contentMode:.fit)
            }
            Text(requestService.status)
        }
    }
}

但是,正如我所说,这超出了这个问题的范围。您可能希望确保熟悉SwiftUI和基本的URLSession编程模式(例如,确保您resume创建的任何任务)。一旦你掌握了这一点,你就可以回来联合编写优雅的网络代码

FWIW与workingdog said一样,您也可以使用^{}的新的异步等待格式副本。但在SwiftUI的声明式世界中,我建议合并

相关问题 更多 >