使用 Combine 解析 phone number String
Using Combine to parse phone number String
我正在努力了解 Combine 的工作原理。当我使用 .assign 运算符来改变我正在操作的 @Published 属性 时,我相信我做错了什么。我已阅读有关发布者、订阅者和运营商的文档。但是如果我不希望它是一个函数调用,我对创建 Publisher 的确切位置有点松散。
import SwiftUI
import Combine
struct PhoneNumberField: View {
let title: String
@ObservedObject var viewModel = ViewModel()
var body: some View {
TextField(title,text: $viewModel.text)
}
class ViewModel: ObservableObject {
@Published var text: String = ""
private var disposables = Set<AnyCancellable>()
init() {
$text.map { value -> String in
self.formattedNumber(number: value)
}
//something wrong here
.assign(to: \.text, on: self)
.store(in: &disposables)
}
func formattedNumber(number: String) -> String {
let cleanPhoneNumber = number.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
let mask = "+X (XXX) XXX-XXXX"
var result = ""
var index = cleanPhoneNumber.startIndex
for ch in mask where index < cleanPhoneNumber.endIndex {
if ch == "X" {
result.append(cleanPhoneNumber[index])
index = cleanPhoneNumber.index(after: index)
} else {
result.append(ch)
}
}
return result
}
}
}
struct PhoneNumberParser_Previews: PreviewProvider {
static var previews: some View {
PhoneNumberField(title: "Phone Number")
}
}
使用.receive(on:)
:
$text.map { self.formattedNumber(number: [=10=]) }
.receive(on: DispatchQueue.main)
.sink(receiveValue: { [weak self] value in
self?.text = value
})
.store(in: &disposables)
这将允许您监听 text
变量的变化并在 main
队列中更新它。如果你想更新一些 View
读取的 @Published
变量,使用 main
队列是必要的。
并且为了避免保留循环(self
-> disposables
-> assign
-> self
)使用 sink
和 weak self
.
我正在努力了解 Combine 的工作原理。当我使用 .assign 运算符来改变我正在操作的 @Published 属性 时,我相信我做错了什么。我已阅读有关发布者、订阅者和运营商的文档。但是如果我不希望它是一个函数调用,我对创建 Publisher 的确切位置有点松散。
import SwiftUI
import Combine
struct PhoneNumberField: View {
let title: String
@ObservedObject var viewModel = ViewModel()
var body: some View {
TextField(title,text: $viewModel.text)
}
class ViewModel: ObservableObject {
@Published var text: String = ""
private var disposables = Set<AnyCancellable>()
init() {
$text.map { value -> String in
self.formattedNumber(number: value)
}
//something wrong here
.assign(to: \.text, on: self)
.store(in: &disposables)
}
func formattedNumber(number: String) -> String {
let cleanPhoneNumber = number.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
let mask = "+X (XXX) XXX-XXXX"
var result = ""
var index = cleanPhoneNumber.startIndex
for ch in mask where index < cleanPhoneNumber.endIndex {
if ch == "X" {
result.append(cleanPhoneNumber[index])
index = cleanPhoneNumber.index(after: index)
} else {
result.append(ch)
}
}
return result
}
}
}
struct PhoneNumberParser_Previews: PreviewProvider {
static var previews: some View {
PhoneNumberField(title: "Phone Number")
}
}
使用.receive(on:)
:
$text.map { self.formattedNumber(number: [=10=]) }
.receive(on: DispatchQueue.main)
.sink(receiveValue: { [weak self] value in
self?.text = value
})
.store(in: &disposables)
这将允许您监听 text
变量的变化并在 main
队列中更新它。如果你想更新一些 View
读取的 @Published
变量,使用 main
队列是必要的。
并且为了避免保留循环(self
-> disposables
-> assign
-> self
)使用 sink
和 weak self
.