gpt4 book ai didi

swift - Bonjour Discovery 的 RxSwift 和嵌套订阅

转载 作者:行者123 更新时间:2023-11-28 11:09:47 24 4
gpt4 key购买 nike

我是 Rx 的新手,一直在尝试制作一个解析服务的 Bonjour 发现客户端。这是非常简单的命令式操作,但我想尝试使用 RxSwift。

由于发现的 NSNetService 对象需要在解析之前持久化,所以我必须进行嵌套订阅调用,外层用于发现,内层 on 用于解析……但有些事情告诉我这不是最好的方式。

import UIKit
import RxSwift

class BonjourClient: NSObject {

let disposeBag = DisposeBag()
var servicesArray = [NSNetService]()

func startBrowsing() {
let browser = NSNetServiceBrowser()
browser.rx_netServiceBrowserDidFindServiceMoreComing
.subscribeNext { (service: NSNetService) in
self.servicesArray.append(service)
self.servicesArray.last!.rx_netServiceDidResolveAddress
.subscribeNext { (sender: NSNetService) in
print("Resolved \(sender.name)")
let data = sender.TXTRecordData()
let dict: [String: NSData?] = NSNetService.dictionaryFromTXTRecordData(data!)
for (key, value) in dict {
print("\(key) : \(String(data: value!, encoding: NSUTF8StringEncoding)!)")
}
}.addDisposableTo(self.disposeBag)
self.servicesArray.last!.resolveWithTimeout(5)
}.addDisposableTo(disposeBag)
browser.searchForServicesOfType("_amzn-wplay._tcp.", inDomain: "local.")
NSRunLoop.currentRunLoop().run()
}

}

我的代理类如下:

import UIKit
import RxSwift
import RxCocoa

class RxNSNetServiceBrowserDelegateProxy: DelegateProxy, NSNetServiceBrowserDelegate, DelegateProxyType {

static func currentDelegateFor(object: AnyObject) -> AnyObject? {
let browser: NSNetServiceBrowser = object as! NSNetServiceBrowser
return browser.delegate
}

static func setCurrentDelegate(delegate: AnyObject?, toObject object: AnyObject) {
let browser: NSNetServiceBrowser = object as! NSNetServiceBrowser
browser.delegate = delegate as? NSNetServiceBrowserDelegate
}

}

class RxNSNetServiceDelegateProxy: DelegateProxy, NSNetServiceDelegate, DelegateProxyType {

static func currentDelegateFor(object: AnyObject) -> AnyObject? {
let service: NSNetService = object as! NSNetService
return service.delegate
}

static func setCurrentDelegate(delegate: AnyObject?, toObject object: AnyObject) {
let service: NSNetService = object as! NSNetService
service.delegate = delegate as? NSNetServiceDelegate
}

}

extension NSNetServiceBrowser {

public var rx_delegate: DelegateProxy {
return proxyForObject(RxNSNetServiceBrowserDelegateProxy.self, self)
}

public var rx_netServiceBrowserDidFindServiceMoreComing: Observable<NSNetService> {
return rx_delegate.observe("netServiceBrowser:didFindService:moreComing:")
.map { params in
let service = params[1] as! NSNetService
return service
}
}

}

extension NSNetService {

public var rx_delegate: DelegateProxy {
return proxyForObject(RxNSNetServiceDelegateProxy.self, self)
}

public var rx_netServiceDidResolveAddress: Observable<NSNetService> {
return rx_delegate.observe("netServiceDidResolveAddress:")
.map { params in
return params[0] as! NSNetService

}
}
}

如果我在 browser.rx_netServiceBrowserDidFindServiceMoreComing 调用之后使用 flatMap 而不是 subscribeNext,服务将无法解析,因为我无法坚持它从 flatMap 中转移到一个数组中,原因让我难以理解,主要是因为我从未接触过 Rx。我一定要使用嵌套调用吗?

我的问题的简短版本是上面的作品,但对我来说似乎很费解。任何想法将不胜感激。

最佳答案

您可以使用scan 来避免嵌套订阅。它会将 rx_netServiceBrowserDidFindServiceMoreComing 中的每个 NSNetService 添加到数组中。请注意,在这种情况下,您不必将 servicesArray 存储为成员变量,除非您出于其他原因需要它。

然后你可以使用flatMap如下:

browser.rx_netServiceBrowserDidFindServiceMoreComing
.scan([NSNetService]()) { (services: [NSNetService], service: NSNetService) in
return services + [service]
}.flatMap { (services: [NSNetService]) in
return services.last!.rx_resolveWithTimeout(5)
}.subscribeNext { (sender: NSNetService) in
print("Resolved \(sender.name)")
let data = sender.TXTRecordData()
let dict: [String: NSData?] = NSNetService.dictionaryFromTXTRecordData(data!)
for (key, value) in dict {
print("\(key) : \(String(data: value!, encoding: NSUTF8StringEncoding)!)")
}
}.addDisposableTo(disposeBag)

这需要在 NSNetService 扩展中添加一个方法,因为您必须从 flatMap 返回一个 Observable:

extension NSNetService {
//existing methods omitted
public func rx_resolveWithTimeout(timeout: NSTimeInterval) -> Observable<NSNetService> {
self.resolveWithTimeout(timeout)
return rx_netServiceDidResolveAddress.filter {
$0 == self
}
}
}

关于swift - Bonjour Discovery 的 RxSwift 和嵌套订阅,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35858805/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com