V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
SorryChen
V2EX  ›  Swift

求助 Alamofire 的 publisher 用法

  •  
  •   SorryChen · Dec 3, 2021 · 2109 views
    This topic created in 1610 days ago, the information mentioned may be changed or developed.

    在学习 macOS 开发想捣鼓个小东西自己用,零基础。这两天研究了研究 Publisher ,感觉也算是大概懂了,但是在用 Alamofire 的 publisher 的时候,怎么也搞不定了。比如如下这个只有一个函数的 APP ,为什么请求不成功呢:

    
    import SwiftUI
    
    import Alamofire
    
    struct ContentView: View {
        var body: some View {
            Text("Hello, world!")
                .padding()
                .onAppear(perform: load)
        }
        
        struct TestResponse: Decodable {
            let userId: Int
            let id: Int
            let title: String
            let body: String
        }
        
        func load(){
            AF.request("https://jsonplaceholder.typicode.com/posts", method: .get, parameters: nil)
                .validate()
                .publishDecodable(type: [TestResponse].self)
                .print()
                .sink { print($0) }
        }
    }
    
    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ContentView()
        }
    }
    
    

    打印出来的是:

    receive subscription: (Alamofire.DataResponsePublisher<Swift.Array<Test.ContentView.TestResponse>>.(unknown context at $1080f8314).Inner<Combine.Publishers.Print<Alamofire.DataResponsePublisher<Swift.Array<Test.ContentView.TestResponse>>>.(unknown context at $7ff81332d748).Inner<Combine.Subscribers.Sink<Alamofire.DataResponse<Swift.Array<Test.ContentView.TestResponse>, Alamofire.AFError>, Swift.Never>>>)
    request unlimited
    receive cancel
    receive value: (failure(Alamofire.AFError.explicitlyCancelled))
    receive finished
    

    为什么会出现 explicitlyCancelled 呢,谢谢大家。

    Supplement 1  ·  Dec 3, 2021
    似乎找到了解释

    As with all Combine usage, care must be taken to ensure that subscriptions are not cancelled early by maintaining the lifetime of the AnyCancellable tokens returned by functions like sink. If a request is cancelled prematurely, the response's error will be set to AFError.explicitlyCancelled.
    Supplement 2  ·  Dec 3, 2021
    找到了答案,
    只需使用一个如 State 来维护 sink 返回的 Cancellable 的生命周期就好了,结贴。
    paopaosa
        1
    paopaosa  
       Dec 3, 2021
    打开外网访问的权限了吗?
    SorryChen
        2
    SorryChen  
    OP
       Dec 3, 2021
    @paopaosa 额谢谢,好像没注意这个事情,我去研究研究,纯 mac 开发新手哈哈
    SorryChen
        3
    SorryChen  
    OP
       Dec 3, 2021
    @paopaosa 您好,在弄了权限之后发现,使用如下方式可以收到数据:

    ```
    AF.request("https://jsonplaceholder.typicode.com/posts", method: .get, parameters: nil)
    .response { r in
    print(r.data)
    }
    ```

    但是 publisher 还是不行
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2512 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 03:54 · PVG 11:54 · LAX 20:54 · JFK 23:54
    ♥ Do have faith in what you're doing.