MST

星途 面试题库

面试题:SwiftUI与Combine框架下如何处理复杂异步数据流

在一个SwiftUI应用中,需要从多个网络API获取数据,这些API调用相互依赖且返回的数据需要经过一系列转换处理后展示在视图上。请说明如何利用Combine框架来管理这些复杂的异步数据流,并描述可能用到的操作符以及SwiftUI视图如何响应这些数据流的变化。
16.9万 热度难度
编程语言Swift

知识考点

AI 面试

面试题答案

一键面试
  1. 利用Combine框架管理异步数据流
    • 创建Publisher:对于每个网络API调用,使用URLSessiondataTaskPublisher(或其他合适的Publisher创建方式)来创建Publisher。例如:
    let url = URL(string: "https://example.com/api")!
    let dataPublisher = URLSession.shared.dataTaskPublisher(for: url)
    
    • 处理依赖关系:使用flatMap操作符来处理API调用的依赖关系。如果API2依赖API1的返回数据,那么可以这样写:
    let api1Publisher = URLSession.shared.dataTaskPublisher(for: api1URL)
       .map(\.data)
       .decode(type: API1Response.self, decoder: JSONDecoder())
    let api2Publisher = api1Publisher.flatMap { api1Data in
       let api2URL = createAPI2URL(from: api1Data)
       return URLSession.shared.dataTaskPublisher(for: api2URL)
          .map(\.data)
          .decode(type: API2Response.self, decoder: JSONDecoder())
    }
    
  2. 可能用到的操作符
    • map:用于将Publisher发出的数据转换为另一种类型。例如将(data: Data, response: URLResponse)转换为具体的模型对象,如map(\.data).decode(type: MyModel.self, decoder: JSONDecoder())
    • decode:专门用于将Data解码为特定的模型类型。
    • flatMap:如上述处理API依赖关系时,将一个Publisher发出的数据作为输入,创建并返回另一个Publisher
    • catch:用于捕获Publisher发出的错误,并提供一个备用的Publisher或者进行错误处理。例如:
    api2Publisher.catch { error in
       // 处理错误,返回一个备用Publisher
       return Just(API2Response.defaultValue)
    }
    
  3. SwiftUI视图响应数据流变化
    • 在SwiftUI视图中,可以使用@StateObject@ObservedObject来观察ObservableObject类型的视图模型。
    • 视图模型中定义一个Published属性来存储处理后的数据流结果。例如:
    class MyViewModel: ObservableObject {
       @Published var finalData: [MyFinalModel] = []
       init() {
          let finalPublisher = api2Publisher
             .map { api2Data in
                // 对api2Data进行一系列转换处理得到MyFinalModel数组
                return convertAPI2DataToFinalModel(api2Data)
             }
          finalPublisher
             .assign(to: \.finalData, on: self)
             .store(in: &cancellables)
       }
       private var cancellables = Set<AnyCancellable>()
    }
    
    • 在SwiftUI视图中使用:
    struct MyView: View {
       @StateObject var viewModel = MyViewModel()
       var body: some View {
          List(viewModel.finalData) { data in
             // 展示数据
             Text(data.description)
          }
       }
    }
    
    viewModel.finalData发生变化时,SwiftUI视图会自动重新渲染,展示最新的数据。