标签: combine

将异步方法转换为组合

我正试图将我的头围绕在 Combine 上。

这是我想转换为Combine 的方法,以便它返回AnyPublisher。

func getToken(completion: @escaping (Result<String, Error>) -> Void) {
    dispatchQueue.async {
        do {
            if let localEncryptedToken = try self.readTokenFromKeychain() {
                let decryptedToken = try self.tokenCryptoHelper.decrypt(encryptedToken: localEncryptedToken)
                DispatchQueue.main.async {
                    completion(.success(decryptedToken))
                }
            } else {
                self.fetchToken(completion: completion)
            }
        } catch {
            DispatchQueue.main.async {
                completion(.failure(error))
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

整个过程在单独的调度队列上执行,因为从 Keychain 读取和解密可能很慢。

我第一次尝试拥抱结合

func getToken() -> AnyPublisher<String, Error> {
    do {
        if let localEncryptedToken = try readTokenFromKeychain() {
            let decryptedToken = try tokenCryptoHelper.decrypt(encryptedToken: localEncryptedToken)
            return Result.success(decryptedToken).publisher.eraseToAnyPublisher()
        } else { …
Run Code Online (Sandbox Code Playgroud)

swift combine

8
推荐指数
1
解决办法
1477
查看次数

如何使用SwiftUI和Combine检测Datepicker的值变化?

在使用 SwiftUI 和 Combine 时,您将如何检测 Datepicker 的值变化?每当移动日期选择器轮时,我都需要调用一个方法,以更新文本和滑块。

我一直在寻找特定的方法来识别值的变化(使用 UIKit 可以将一个动作与一个事件相关联),但显然我没有在文档中找到任何有用的东西(我已经尝试过 onTapGesture 方法,但这不是我想要什么,因为它强制用户点击选择器来更新其他视图,而我希望在用户移动轮子时自动更新)。

import SwiftUI

struct ContentView: View {

    private var calendar = Calendar.current

    @State private var date = Date()
    @State private var weekOfYear = Double(Calendar.current.component(.weekOfYear, from: Date()) )
    @State private var lastWeekOfThisYear = 53.0
    @State private var weekDay: String = { () -> String in 
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "EEEE"
        let weekDay = dateFormatter.string(from: Date())
        return weekDay
    }()

    var body: some View {

        VStack {

            // Date Picker …
Run Code Online (Sandbox Code Playgroud)

events datepicker valuechangelistener swiftui combine

8
推荐指数
2
解决办法
5224
查看次数

URLSession.shared.dataTaskPublisher 不适用于 IOS 13.3

尝试发出网络请求时,出现错误

finished with error [-999] Error Domain=NSURLErrorDomain Code=-999 "cancelled"
Run Code Online (Sandbox Code Playgroud)

如果我使用它URLSession.shared.dataTask而不是URLSession.shared.dataTaskPublisher它将在 IOS 13.3 上工作。

这是我的代码:

return  URLSession.shared.dataTaskPublisher(for : request).map{ a in
    return a.data
}
.decode(type: MyResponse.self, decoder: JSONDecoder())
.receive(on: DispatchQueue.main)
.eraseToAnyPublisher()
Run Code Online (Sandbox Code Playgroud)

此代码适用于 IOS 13.2.3。

swift swiftui combine ios13.3

8
推荐指数
2
解决办法
3803
查看次数

如何压缩超过 4 个出版商

我正在为我的 API 请求使用 Swift Combine。现在我面临的情况是,我想要将 4 个以上的并行请求压缩在一起。在我使用 Zip4() 运算符将 4 个请求压缩在一起之前。我可以想象您分多个步骤进行压缩,但我不知道如何为其编写 receiveValue。

这是我当前代码的简化,包含 4 个并行请求:

    Publishers.Zip4(request1, request2, request3, request4)
        .sink(receiveCompletion: { completion in
            // completion code if all 4 requests completed
        }, receiveValue: { request1Response, request2Response, request3Response, request4Response in
            // do something with request1Response
            // do something with request2Response
            // do something with request3Response
            // do something with request4Response
        }
    )
        .store(in: &state.subscriptions)
Run Code Online (Sandbox Code Playgroud)

swift combine

8
推荐指数
3
解决办法
3755
查看次数

结合转换为 AnyPublisher

如何转换Just<[Int]>AnyPublisher<[Int], Error>. 当我使用eraseToAnyPublisher()类型是AnyPublisher<[Int], Never>这与AnyPublisher<[Int], Error>

例如,我有一个简单的函数,我想临时模拟它

func getAllIds() -> AnyPublisher<[Int], Error> {
    return Just<[Int]>([]).eraseToAnyPublisher()
}
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

ios swift combine

8
推荐指数
1
解决办法
1901
查看次数

组合:不能将 `.assign` 与结构一起使用 - 为什么?

在尝试使用Combine 分配值时,我看到了一些我不太理解的结构与类行为。

代码:

import Foundation
import Combine

struct Passengers {
  var women = 0
  var men = 0
}

class Controller {
  @Published var passengers = Passengers()
  var cancellables = Set<AnyCancellable>()
  let minusButtonTapPublisher: AnyPublisher<Void, Never>

  init() {
    // Of course the real code has a real publisher for button taps :)
    minusButtonTapPublisher = Empty<Void, Never>().eraseToAnyPublisher()

    // Works fine:
    minusButtonTapPublisher
      .map { self.passengers.women - 1 }
      .sink { [weak self] value in
        self?.passengers.women = value
      }.store(in: &cancellables)

    // Doesn't work:
    minusButtonTapPublisher …
Run Code Online (Sandbox Code Playgroud)

swift combine

8
推荐指数
2
解决办法
1364
查看次数

将订阅存储到订阅集中的原因是什么?

组合订阅示例代码片段全部将生成的订阅存储到集合subscriptions

private var subscriptions = Set<AnyCancellable>()
Run Code Online (Sandbox Code Playgroud)

为什么我们需要这样做?

future
  .sink(receiveCompletion: { print($0) }, receiveValue: { print($0) }) 
  .store(in: &subscriptions)
Run Code Online (Sandbox Code Playgroud)

swift combine

8
推荐指数
1
解决办法
1931
查看次数

AnyCancellable.store(in:) 与合并

让\xe2\x80\x99s 假设您正在 AnyCancellable 上使用内置.store(in:)方法,如下所示:

\n
private var subscriptions = Set<AnyCancellable>()\n\nlet newPhotos = photos.selectedPhotos\nnewPhotos\n  .map { [unowned self] newImage in\n    return self.images.value + [newImage]\n  }\n  .assign(to: \\.value, on: images)\n  .store(in: &subscriptions)\n
Run Code Online (Sandbox Code Playgroud)\n

如果您有一个经常执行此操作的应用程序 - 发布商完成后这些内容是否会被删除?

\n

另外,如果我决定采用这种方法:

\n
private var newPhotosSubscription: AnyCancellable?\n\nself.newPhotosSubscription = newPhotos\n  .map { [unowned self] newImage in\n    self.images.value + [newImage]\n  }\n  .assign(to: \\.value, on: images)\n
Run Code Online (Sandbox Code Playgroud)\n

每次我再次调用该方法时,它都会覆盖 AnyCancellable,前一个会发生什么?它在被释放之前是否仍然完成?

\n

swift combine

8
推荐指数
1
解决办法
6935
查看次数

嵌套 ObservedObject 中的更改不会更新 UI

当我有一个嵌套的 ObservedObject 时,嵌套对象的已发布属性的更改不会更新 UI,直到父对象发生某些情况。这是一个功能、一个错误(在 SwiftUI 中)还是我的代码中的一个错误?

这是一个简化的示例。单击父级的开/关按钮会立即更新 UI,但单击子级的开/关按钮不会更新,直到父级更新为止。

我正在运行 Xcode 12.5.1。

import SwiftUI

class NestedObject: NSObject, ObservableObject {
    @Published var flag = false
}
class StateObject: NSObject, ObservableObject {
    @Published var flag = false
    @Published var nestedState = NestedObject()
}

struct ContentView: View {
    @ObservedObject var state = StateObject()
    var body: some View {
        VStack {
            HStack {
                Text("Parent:")
                Button(action: {
                    state.flag.toggle()
                }, label: {
                    Text(state.flag ? "On" : "Off")
                })
            }
            HStack {
                Text("Child:")
                Button(action: {
                    state.nestedState.flag.toggle()
                }, label: …
Run Code Online (Sandbox Code Playgroud)

swiftui combine

8
推荐指数
2
解决办法
3669
查看次数

致命错误:UnsafeRawBufferPointer 从 Core Data/NSFetchedResultsController 删除对象时计数为负

这是我第一次使用 AppKit 和NSTableView. 它由NSFetchedResultsController核心数据支持。当数据集发生更改时,Notification将发送:

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
    guard let links = self.fetchedResultsController.fetchedObjects else {
        return
    }

    if self.viewContext.hasChanges {
        try? self.viewContext.save()
    }
        
    self._links = links
    NotificationCenter.default.post(name: .reloadLinkList, object: nil)
}
Run Code Online (Sandbox Code Playgroud)
NotificationCenter.default.publisher(for: .reloadLinkList).receive(on: RunLoop.main).sink { notification in
    self.list.tableView.reloadData()
    self.list.linksModel.selectedRows = IndexSet([])
}
.store(in: &cancellables)
Run Code Online (Sandbox Code Playgroud)

这对于插入和更新数据非常有用。当我尝试删除某些内容时,我得到:

Thread 1: Fatal error: UnsafeRawBufferPointer with negative count
Run Code Online (Sandbox Code Playgroud)

删除选定对象的代码如下:

Thread 1: Fatal error: UnsafeRawBufferPointer with negative count …
Run Code Online (Sandbox Code Playgroud)

macos appkit nsfetchedresultscontroller swift combine

8
推荐指数
1
解决办法
2167
查看次数