标签: combine

在 flatMap 运算符闭包中放置打印语句后,结合奇怪的编译错误

stories我有Ray Wenderlich 所著的合并书中的以下方法(名为:) ,它从Hacker News Public API中获取故事,如下所示:

模型对象:

public struct Story: Codable {
  public let id: Int
  public let title: String
  public let by: String
 public let time: TimeInterval
 public let url: String
}

extension Story: Comparable {
  public static func < (lhs: Story, rhs: Story) -> Bool {
  return lhs.time > rhs.time
  }
}

extension Story: CustomDebugStringConvertible {
   public var debugDescription: String {
   return "\n\(title)\nby \(by)\n\(url)\n-----"
  }
}
Run Code Online (Sandbox Code Playgroud)

API结构:

struct API {
  enum Error: LocalizedError { …
Run Code Online (Sandbox Code Playgroud)

ios swift combine

0
推荐指数
1
解决办法
632
查看次数

将回调方法转变为通过组合进行反应

这就是我正在做的:

-> 使用 FirebaseAuthentification 登录/注册 Firebase

-> 监听 AuthStateDidChangeListenerHandle

-> 我在 Firestore 中存储额外的用户信息,因此我检查 Firestore 中是否存在该用户

-> 如果用户不存在,我创建一个空用户

-> 如果一切成功,我通过回调返回未来发布者(我也想更改它)

这是 checkLoginState 函数:

func checkLoginState(completion: @escaping (AnyPublisher<AccountDetails,Error>) -> Void) {
    self.handler = Auth.auth().addStateDidChangeListener { [weak self] auth, user in
        guard let safeSelf = self else { return }
        completion(Future<AccountDetails,Error> { promise in
            if let user = user {
                print(user)
                print(auth)

                safeSelf.checkIfUserIsInDatabase(user: user.uid) { result in
                    switch result {
                    case .success(let isAvailable):
                        if isAvailable {
                             promise(.success(AccountDetails(userUID: user.uid,name: user.displayName, loggedIn: true, premiumUser: false))) …
Run Code Online (Sandbox Code Playgroud)

future publisher firebase swift combine

0
推荐指数
1
解决办法
1895
查看次数

快速组合。从超时处理程序块返回的正确方法是什么?

我需要在组合中实现超时函数的处理程序。让我们考虑以下代码结构:

SomeKindOfPublisher<Bool, Never>()
   .timeout(timeoutInterval, scheduler: backgroundQueue,
      customError: { [weak self] () -> Never in
         ...
         while true {} // This block should not return because of Never
      }
Run Code Online (Sandbox Code Playgroud)

我的问题是如何避免出现奇怪的线条while true {}?我不想将 Never 更改为 Error 类型。

swift combine

0
推荐指数
1
解决办法
3931
查看次数

发布者发布运营进度和最终价值

鉴于我有一个提供以下功能的 SDK

class SDK {
    static func upload(completion: @escaping (Result<String, Error>) -> Void) {
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
            completion(.success("my_value"))
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我能够创建一个包装器以使其使用更实用

class CombineSDK {
    func upload() -> AnyPublisher<String, Error> {
        Future { promise in
            SDK.upload { result in
                switch result {
                case .success(let key):
                    promise(.success(key))
                case .failure(let error):
                    promise(.failure(error))
                }
            }
        }.eraseToAnyPublisher()
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我试图了解如果 SDK 上传方法还提供如下所示的进度块,我的 JointSDK.upload 方法应该是什么样子:

class SDK {
    static func upload(progress: @escaping (Double) -> Void, completion: @escaping (Result<String, Error>) -> Void) {
        DispatchQueue.main.asyncAfter(deadline: …
Run Code Online (Sandbox Code Playgroud)

swift combine

0
推荐指数
1
解决办法
865
查看次数

Swift 合并 HTTP 请求

试图弄清楚如何使用组合快速发出 http 请求。我主要是在看Apple 的这个文档。我没有取得任何进展,而且看起来很简单,所以我不知道我做错了什么。

我习惯使用 JavaScript 并使用Fetch API
也使用Golang 中的http pkg
但出于某种原因,在 Swift 中这样做对我来说真的很困惑,因为它不像我提到的两个那样精简

我将 SwiftUI 与 MVVM 架构一起使用,所以我的目标是在我的视图模型中实现一种与 Golang 服务器通信的方式。

这就要求大多POST与请求AcceptAuthorization头部和JSON身体

我试过这个代码:

let url = URL(string: "https://api.example.com/user/login")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.setValue(String(format: "Bearer %s", idToken!), forHTTPHeaderField: "Authorization")
        
_ = URLSession.shared.dataTaskPublisher(for: request)
    .tryMap() { element -> Data in
        // not worried about the status code just trying to get any response. …
Run Code Online (Sandbox Code Playgroud)

http ios swift combine

0
推荐指数
1
解决办法
1761
查看次数

使用Combine,你怎么能用nil-coalescing 进行flatMap

我有一个发布可选输出类型的发布者。flatMap如果输出不是nil,我需要到一个新的发布者,如果是,则回退到一个空的发布者nil

例如,类似于:

[1, nil, 5].publisher // Generic parameter 'T' could not be inferred
    .flatMap {
        $0?.someNewPublisher ?? Empty(completeImmediately: false)
    }
Run Code Online (Sandbox Code Playgroud)
[1, nil, 5].publisher
    .map {
        $0?.someNewPublisher
    }
    .replaceNil(with: Empty(completeImmediately: false)) // Generic parameter 'Failure' could not be inferred
    .flatMap { $0 }

Run Code Online (Sandbox Code Playgroud)

我想知道我是否试图以错误的方式解决这个问题。需要明确的是,nil在映射之前过滤并不能解决我的问题,因为这不会用一个空的发布者替换当前的发布者(我将继续接收我不应该再接收的元素)。

reactive-programming ios swift combine

0
推荐指数
1
解决办法
901
查看次数

使用组合网络 ios 刷新令牌

这个问题很简单:

我的代码:

        return urlSession.dataTaskPublisher(for: urlRequest)
        .tryMap { (data: Data, response: URLResponse) -> Data in
            //TODO: hide loader
            GRP.hideLoader()
            if let httpURLResponse = response as? HTTPURLResponse {
                if !(200...299 ~= httpURLResponse.statusCode) {
                    var error = NetworkingError(errorCode: httpURLResponse.statusCode)
                    if let json = try? JSONSerialization.jsonObject(with: data, options: []) {
                        error.jsonPayload = json
                    }
                    throw error
                }
            }
            
            if withErrorMessage, let errorCheckModel = try? JSONDecoder().decode(ErrorModel.self, from: data)
            {
                if let statusIsSuccess = errorCheckModel.success, let errorMessage = errorCheckModel.message, !errorMessage.isEmpty
                {
                    if(!statusIsSuccess)
                    {
                        print(urlString)
                        GRP.showToast(failure: true, …
Run Code Online (Sandbox Code Playgroud)

ios swift refresh-token swiftui combine

0
推荐指数
1
解决办法
1286
查看次数

无法将“Published&lt;[StepsEntity]&gt;.Publisher”类型的值转换为预期参数类型“Binding&lt;String&gt;”

StepsEntity是核心数据实体

尝试在 TextField 中显示字符串值时收到以下错误:“无法将类型 'Published<[StepsEntity]>.Publisher' 的值转换为预期参数类型 'Binding'”

我知道这是因为我的核心数据模型中的 StepsEntity 是 @Published。@Published 在这里效果很好,因为它允许整齐地更新所有数据。如何在文本字段中显示@Published?

以下是我收到错误的部分:

List {
            VStack(alignment: .center) {
                if let recipeSteps = (vm.recipes[vm.getRecordsCount() - 1].steps?.allObjects as? [StepsEntity])?.sorted { $0.stepNumber < $1.stepNumber } {
                    
                    if (textFieldCount == 1) {
                        //do nothing
                    } else if (textFieldCount > 1) {
                        ForEach(recipeSteps, id: \.stepNumber) { index in
                            HStack {
                               
                                Text(String(index.stepNumber) + ".").bold()
                                TextField("", text: vm.$recipeSteps) //This is where the error is seen
                                
                            }
                        }.onDelete(perform: { index in
                            self.vm.deleteRecipeSteps(at: index, from: vm.recipes[vm.getRecordsCount() - 1])
                            }) …
Run Code Online (Sandbox Code Playgroud)

binding swift swiftui combine

0
推荐指数
1
解决办法
3870
查看次数

创建一个发布者,该发布者在另一个发布者完成时发出值

我有一个从不发出项目并且仅完成或失败并出现错误 ( AnyPublisher<Never, Error>) 的发布者。AnyPublisher<Value, Error>我想将该发布者转换为在第一个发布者完成 ( ) 或传递任何错误时发出值的发布者。我想在第一个发布商完成后创造该价值。我可以做这样的事情,但看起来很混乱:

func demo() -> AnyPublisher<Int, Error> {
    // Using Empty just for demo purposes
    let firstPublisher = Empty<Never, Error>(completeImmediately: true).eraseToAnyPublisher()
    var cancellable: AnyCancellable?
    return Future<Int, Error> { promise in
        cancellable = firstPublisher
            .sink { completion in
                switch completion {
                case .failure(let error):
                    promise(.failure(error))
                case .finished:
                    // some operation that generates value
                    let value:Int = 1
                    promise(.success(value))
                }
            } receiveValue: { _ in
            }
    }
    .handleEvents(receiveCancel: {
        cancellable?.cancel()
    })
    .eraseToAnyPublisher() …
Run Code Online (Sandbox Code Playgroud)

swift combine

0
推荐指数
1
解决办法
1382
查看次数

What does the dollar sign do in this example?

This tutorial by Apple about SwiftUI uses a dollar sign to bind data, and I‘m having trouble finding more information about this data binding in SwiftUI.

Is this some sort of inout type parameter? That uses the ampersand to pass it on.

swift swiftui combine

-2
推荐指数
2
解决办法
1039
查看次数