Hello Everyone,
I'm now facing a issue that number counting won't work correctly when I use Notification Center(I tried to narrow down the problem area as below's code and Notification Center seems to be problem's root)
I suspect that the problem cause from Thread location or reference on NotificationCenter's handler when observing value change. So, I think that If I can change thread location or reference following thread location or reference of the method that defined addObserver.
Am I correct? and does someone know how to make the code correct?
Code is below
ContentView.swift
struct ContentView: View {
@ObservedObject var cht = CompletionHandlerTest()
var body: some View {
Button(action:{
cht.startCount(list: ["A", "B","C", "D", "E"]){ isCompleteCount in
print("countEnd")
}
}){
Text("start")
}
.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
CompletionHandlerTest.swift
import SwiftUI
public class CompletionHandlerTest: ObservableObject {
@Published var counter: Int = 0
private let nbc = NotificationBasedCompletion.shared
func startCount(list: [String], completion: @escaping(Bool) -> Void) {
print("count start")
countTest(items: list, count: 0){ isSuccessful in
completion(true)
print("countTest is finished")
}
}
private func countTest(items: [String], count: Int, completion: @escaping(Bool) -> Void){
if(count >= items.count){
completion(true)
}
else {
print("count in countTest -> \(count)")
nbc.notifyForTest(label: items[count]){ isPrintSuccessful in
print("countTest will call-> count: \(count) + 1")
DispatchQueue.main.asyncAfter(deadline: .now() + 0.7) {
self.countTest(items: items, count: count+1) { isCountSuccessful in
completion(true)
}
}
}
}
}
}
NotificationBasedCompletion.swift
final public class NotificationBasedCompletion: NSObject{
public static let shared = NotificationBasedCompletion()
private var observer: NSObjectProtocol?
func notifyForTest(label: String, completion: @escaping (Bool) -> Void ){
if(observer == nil){
observer = NotificationCenter.default.addObserver(forName: NSNotification.Name("notifyStatus"), object: nil, queue: .main){ (_) in
let notifyStatus = UserDefaults.standard.value(forKey: "notifyStatus") as? Bool ?? false
if notifyStatus {
completion(true)
}
}
}
//if below code is used, count won't proceed
generateNotification()
// if below code is used, count will count correctly
//completion(true)
}
private func generateNotification() {
print("let's notify!")
UserDefaults.standard.set(true, forKey: "notifyStatus")
NotificationCenter.default.post(name:NSNotification.Name("notifyStatus"), object: nil)
}
}
When executing above code, then print as below
count start
count in countTest -> 0
let's notify!
countTest will call-> count: 0 + 1
count in countTest -> 1
let's notify!
countTest will call-> count: 0 + 1
count in countTest -> 1
let's notify!
countTest will call-> count: 0 + 1
count in countTest -> 1
I hope that someone knows about the issue. Best regards,