@@ -42,7 +42,33 @@ public extension Bus { | |||||
.sink { v in handler(v.0, v.1) } | .sink { v in handler(v.0, v.1) } | ||||
.store(in: &subscriptions) | .store(in: &subscriptions) | ||||
} | } | ||||
static func receiveAsync<T>( | |||||
_ subscriptions: inout Set<AnyCancellable>, | |||||
_ keys: Set<String>, | |||||
_ handler: @escaping ((String, T) -> Void) | |||||
) { | |||||
Service.singleton?.broadcaster | |||||
.compactMap { v -> (String, T)? in | |||||
guard | |||||
keys.contains(v.key), | |||||
let value = v.value as? T | |||||
else { | |||||
return nil | |||||
} | |||||
return (v.key, value) | |||||
} | |||||
.receive(on: DispatchQueue.main) | |||||
.sink { v in handler(v.0, v.1) } | |||||
.store(in: &subscriptions) | |||||
} | |||||
static func send(_ key: String, _ value: Any) { | |||||
Service.singleton?.send(key, value) | |||||
} | |||||
/* | |||||
static func sendAsync<T: Equatable>( | static func sendAsync<T: Equatable>( | ||||
_ subscriptions: inout Set<AnyCancellable>, | _ subscriptions: inout Set<AnyCancellable>, | ||||
_ key: String, | _ key: String, | ||||
@@ -53,4 +79,5 @@ public extension Bus { | |||||
.sink { v in Service.singleton?.send(key, v) } | .sink { v in Service.singleton?.send(key, v) } | ||||
.store(in: &subscriptions) | .store(in: &subscriptions) | ||||
} | } | ||||
*/ | |||||
} | } |
@@ -8,7 +8,17 @@ enum MeetupId { | |||||
} | } | ||||
static func shouldFormat(_ s: String) -> String? { | static func shouldFormat(_ s: String) -> String? { | ||||
s.components(separatedBy: NSCharacterSet.decimalDigits.inverted).reduce("") { $0 + $1 } | |||||
let digits = s.components(separatedBy: NSCharacterSet.decimalDigits.inverted).reduce("") { $0 + $1 } | |||||
var r = "" | |||||
var i = 0 | |||||
for v in digits { | |||||
r += String(v) | |||||
i = i + 1 | |||||
if i % 3 == 0 { | |||||
r += "-" | |||||
} | |||||
} | |||||
return r | |||||
} | } | ||||
final class MeetupIdFormatter { | final class MeetupIdFormatter { | ||||
@@ -22,15 +32,15 @@ enum MeetupId { | |||||
Bus.receive( | Bus.receive( | ||||
&subscriptions, | &subscriptions, | ||||
[Keys.meetupIdTextUI.rawValue], | [Keys.meetupIdTextUI.rawValue], | ||||
{ [weak self] k, v in self?.handleFormatting(k, v) } | |||||
Self.handleFormatting | |||||
) | ) | ||||
/**/print("ИГР MeetupIF.init") | /**/print("ИГР MeetupIF.init") | ||||
} | } | ||||
func handleFormatting(_: String, _ value: String) { | |||||
static func handleFormatting(_: String, _ value: String) { | |||||
let out = MeetupId.shouldFormat(value) | let out = MeetupId.shouldFormat(value) | ||||
/**/print("ИГР MeetupIF.handleF out/dt: '\(out)'/'\(Date())'") | /**/print("ИГР MeetupIF.handleF out/dt: '\(out)'/'\(Date())'") | ||||
Bus.Service.singleton?.send(Keys.meetupIdTextApp.rawValue, out) | |||||
Bus.send(Keys.meetupIdTextApp.rawValue, out) | |||||
} | } | ||||
} | } | ||||
/* | /* | ||||
@@ -2,7 +2,7 @@ import Foundation | |||||
class SrcFmt: Formatter { | class SrcFmt: Formatter { | ||||
override func string(for obj: Any?) -> String? { | override func string(for obj: Any?) -> String? { | ||||
/**/print("ИГР SrcF.string obj: '\(obj)'") | |||||
/**///print("ИГР SrcF.string obj: '\(obj)'") | |||||
guard let str = obj as? String else { return nil } | guard let str = obj as? String else { return nil } | ||||
return String(str.dropFirst(2)) | return String(str.dropFirst(2)) | ||||
} | } | ||||
@@ -12,11 +12,13 @@ class SrcFmt: Formatter { | |||||
for string: String, | for string: String, | ||||
errorDescription error: AutoreleasingUnsafeMutablePointer<NSString?>? | errorDescription error: AutoreleasingUnsafeMutablePointer<NSString?>? | ||||
) -> Bool { | ) -> Bool { | ||||
/**/print("ИГР SrcF.getOV string: '\(string)'") | |||||
/**///print("ИГР SrcF.getOV string: '\(string)'") | |||||
let val: String | let val: String | ||||
if string.hasPrefix("a:") || string.hasPrefix("u:") { | if string.hasPrefix("a:") || string.hasPrefix("u:") { | ||||
/**///print("ИГР SrcF.getOV-1") | |||||
val = string | val = string | ||||
} else { | } else { | ||||
/**///print("ИГР SrcF.getOV-2") | |||||
val = "u:\(string)" | val = "u:\(string)" | ||||
} | } | ||||
obj?.pointee = val as AnyObject | obj?.pointee = val as AnyObject | ||||
@@ -7,7 +7,7 @@ struct V: View { | |||||
VStack { | VStack { | ||||
HStack { | HStack { | ||||
Text("Check text field:") | Text("Check text field:") | ||||
Text("'\(vm.text)'") | |||||
Text("'\(vm.t3)'") | |||||
.fontWeight(.bold) | .fontWeight(.bold) | ||||
} | } | ||||
/* | /* | ||||
@@ -2,30 +2,38 @@ import Combine | |||||
import SwiftUI | import SwiftUI | ||||
final class VM: ObservableObject { | final class VM: ObservableObject { | ||||
/* | |||||
@Published var text = "" | @Published var text = "" | ||||
let changeText = PassthroughSubject<String, Never>() | let changeText = PassthroughSubject<String, Never>() | ||||
@Published var t2 = "a:value" | @Published var t2 = "a:value" | ||||
var bt2: Binding<String>! | var bt2: Binding<String>! | ||||
var subscriptions = Set<AnyCancellable>() | |||||
*/ | |||||
@Published var t3 = "a:value" | @Published var t3 = "a:value" | ||||
var subscriptions = Set<AnyCancellable>() | |||||
init() { | init() { | ||||
$t3 | $t3 | ||||
//.debounce(for: .seconds(0.3), scheduler: DispatchQueue.main) | |||||
.debounce(for: .seconds(0.3), scheduler: DispatchQueue.main) | |||||
.sink { v in | .sink { v in | ||||
/**/print("ИГР VM.init t3: '\(v)'") | /**/print("ИГР VM.init t3: '\(v)'") | ||||
// Ignore repoting application initiated strings | // Ignore repoting application initiated strings | ||||
// Only report user initiated strings | // Only report user initiated strings | ||||
//guard v.hasPrefix("u:") else { return } | |||||
//Bus.Service.singleton?.send(MeetupId.Keys.meetupIdTextUI.rawValue, String(v.dropFirst(2))) | |||||
guard v.hasPrefix("u:") else { return } | |||||
Bus.send(MeetupId.Keys.meetupIdTextUI.rawValue, String(v.dropFirst(2))) | |||||
} | } | ||||
.store(in: &subscriptions) | .store(in: &subscriptions) | ||||
Bus.receiveAsync( | |||||
&subscriptions, | |||||
[MeetupId.Keys.meetupIdTextApp.rawValue], | |||||
{ [weak self] _, v in self?.applyFormattedValue(v) } | |||||
) | |||||
/* | |||||
bt2 = Binding<String>( | bt2 = Binding<String>( | ||||
get: { [weak self] in | get: { [weak self] in | ||||
String(self?.t2.dropFirst(2) ?? "") | String(self?.t2.dropFirst(2) ?? "") | ||||
@@ -75,15 +83,12 @@ final class VM: ObservableObject { | |||||
self?.text = out | self?.text = out | ||||
} | } | ||||
.store(in: &subscriptions) | .store(in: &subscriptions) | ||||
*/ | |||||
} | } | ||||
func handleAppValue(_: String, _ value: String) { | |||||
/**/print("ИГР VM.handleAV value: '\(value)'") | |||||
/* | |||||
DispatchQueue.main.async { [weak self] in | |||||
self?.t2 = value | |||||
} | |||||
*/ | |||||
func applyFormattedValue(_ value: String) { | |||||
/**/print("ИГР VM.handleFV value: '\(value)'") | |||||
t3 = "a:\(value)" | |||||
} | } | ||||
} | } |