I have a UIViewController with instance variables (properties).
This VC calls methods via a singleton of a Utilities class that interacts with the data.
For local synchronous calls, everything works fine. However, if no local data is found, the system makes asynchronous calls to remote resources via methods located not in the Utilities class but in the View Controller. (I know ideally they would not be in the VC but that is the current set up). If a method in the Utilities class, calls a method in the original view controller--via a singleton, I am finding that the methods lack access to previously set instance variables. The instance variables in the VC are empty.
It is almost as though (and may be) that a fresh instance of the class has been created that lacks values for properties set in the original instance of the class. Is that the case?
I know that the data has not disappeared from the original VC because when I send a notification to the original VC, the listener in that VC is able to retrieve values held in the VC's properties. However, the instance variables within the fresh singleton of the VC are all empty and methods in the VC called in this way find the instance variables devoid of data.
The pattern is roughly:
VC (with populated instance variables).method calls--->
Utilities.sharedInstance.method calls--->
VC.sharedInstance.method (instance variables now empty)
Is it the case that if you access a class via a singleton, you create a new instance that lacks the values that were in the original class?
How can I call methods in the Utilities class such that if they call methods back in the original VC, the original properties are available?
Note: If possible, I would like to find a solution that does not involve moving the asynchronous call out of the View Controller as architecture is outside my purview.
Thanks in advance for any suggestions. Streamlined code:
//Original VIEW CONTROLLER
class MyVC : UIViewController {
static var shared = MyVC()
var messages : [[String: String]] = [
["role": "bot", "content": "How can I help you"],
["role": "user", "content": "What is my balance"]
]
Utilities.sharedInstance()?.getAnswer(messages) {
answer,error in
if (answer != nil) {
//display answer
}
else {
//A call is made to remote resources and an async answer will be returned via notification
}
}
@objc func receivedAnswer ( _ notification : Notification ) {
if let text = notification.object as? String {
DispatchQueue.main.async {//open 2
//display answer from notification
}
}
}
@objc func getAsyncAnswer (messages:Array?,completion:@escaping (_ response:String)->()){//open 1 method
//send notification with answer
}
//Utilities class (Obj-c)
@implementation Utilities
+(Utilities*) sharedInstance{
//GCD returns create sharedInstance
return sharedInstance;
}
-(NSString* ) getAnswer (NSArray* messages) {
//Check local knowledge base
NSString * answer = [self searchLocalKnowledgeBase:messages];
if (answer != @"") {
return answer;
}
else {
//async call to external resoures that sends notification
[[MyVC shared] getAsyncAnswerWithMessages: messages completion:^(NSString* answer){
//send notification with Answer
}];
}
return nil;
}