Reputation: 63
I have an instance in a view called "PayView" and at the meantime I am doing openURL to open a separate app and to pass some data to it. This second app process the information I send and gives the response back.
At Appdelegate.m I have this handleOpenUrl which receives the response sent by the second app. Once I receive the response back I would like to go back to my "PayView" and use the response received from the second app along with already existing values I have in the instance.
My problem is as soon as the response from the second app reaches the appdelegate and reached the section "return yes", my main app goes back to this "PayView" and does nothing.
So how do I use the response object I received from appdelegate at my PayView along with already existing instance values?
I thought about using a global variable to store the "payView" instance/object and initiate a new instance from appdelegate for "Payview" and use the global along with the response json from appdelegate. However, I found many forums advising against using global.
So, ignoring the global and crating a new instance for "payview" causes loss of all previously stored data.
I am not an experienced iOS programmer and just work momentarily on someone else code.So, hope I explained my issue/question.
It would be great if I could get some valuable inputs :)
My appdelegate.m look like this,
-(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{
if (!url) {
return NO;
}
// Unencode the URL's query string
NSString *queryString = [[url query] stringByRemovingPercentEncoding];
// Extract the JSON string from the query string
queryString = [queryString stringByReplacingOccurrencesOfString:@"response=" withString:@""];
// Convert the JSON string to an NSData object for serialization
NSData *queryData = [queryString dataUsingEncoding:NSUTF8StringEncoding];
// Serialize the JSON data into a dictionary
NSDictionary* jsonObject = [NSJSONSerialization JSONObjectWithData:queryData options:0 error:nil];
NSString *response = [jsonObject objectForKey:@"Result"]; //Get the response
UIAlertView *alert1 = [[UIAlertView alloc] initWithTitle:@"Result" message:response delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
[alert1 show];
//PayView *pdv = [[PayViewController alloc] init];
//[pdv UseTransactionResult:jsonObject] ;
return YES;
}
and this is how I am calling open url from PayView
[[UIApplication sharedApplication]openURL:[NSURL URLWithString:[NSString stringWithFormat:@"mysecondapp://v2/data/?request=%@",requestEncodedString]] options:@{} completionHandler:^(BOOL success) {
if (success)
{
NSLog(@"Opened url");
}
}];
Hi @ekscrypto, thanks for your valuable input. It is really helpful. I just have one problem with this. It is working just fine when I do the following in my PayView
Receiver:
[[NSNotificationCenter defaultCenter] addObserverForName:@"ActionIsComplete" object:nil queue:nil usingBlock:^(NSNotification *note){
//Completed Action
NSString *response = [note.userInfo objectForKey:@"Result"]; //Get the response
NSLog(response);
[self dismissViewControllerAnimated:YES completion:nil];
}];
However, when I try to do the same in the following method I get error "unrecognized selector sent to instance"
Receiver:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(ReceiveActionIsComplete:) name:@"ActionIsComplete" object:nil];
-(void)ReceiveActionIsComplete:(NSNotification *) notification
{
NSDictionary *jsonObject = (NSDictionary *)notification.userinfo;
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"ActionIsComplete" object:nil];
Status = [jsonObject objectForKey:@"Status"];
Result = [jsonObject objectForKey:@"Result"];
NSLog([NSString stringWithFormat:@"%@%@",@"Status is: ", Status]);
NSLog([NSString stringWithFormat:@"%@%@",@"Result is: ", Result]);
}
in both cases my sender at Appdelegate looks like this.
Sender:
[[NSNotificationCenter defaultCenter] postNotificationName:@"ActionIsComplete" object:nil userInfo:jsonObject];
FYI: I tried sending the object in object instead of userInfo as well.
So what I am doing wrong? could you please help me.
Sender: (AppDelegate.m)
[[NSNotificationCenter defaultCenter] postNotificationName:@"ActionIsComplete" object:nil userInfo:jsonObject];
Receiver: (PayView.m)
under - (void)viewDidLoad
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(ReceiveActionIsComplete:) name:@"ActionIsComplete" object:nil];
and the function to receive the results
-(void)ReceiveActionIsComplete:(NSNotification *) notification
{
NSDictionary *jsonObject = (NSDictionary *)notification.userInfo;
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"ActionIsComplete" object:nil];
Status = [jsonObject objectForKey:@"Status"];
Result = [jsonObject objectForKey:@"Result"];
NSLog([NSString stringWithFormat:@"%@%@",@"Status is: ", Status]);
NSLog([NSString stringWithFormat:@"%@%@",@"Result is: ", Result]);
}
Upvotes: 1
Views: 1195
Reputation: 3816
You could register a NotificationCenter observer in your PayView, and post a notification from your AppDelegate when the response is received. Via the notification object
you can forward any information you need.
Let's assume that you define a struct with the information you want to pass along:
struct PaymentConfirmation {
let amount: Float
let confirmationNumber: String
}
In your PayView:
class PayView: UIView {
...
static let paymentProcessedNotification = NSNotification.Name("PayView.paymentProcessed")
let paymentProcessedObserver: NSObjectProtocol?
override func viewDidLoad() {
super.viewDidLoad()
paymentProcessedObserver = NotificationCenter.default.addObserver(
forName: PayView.paymentProcessedNotification,
object: nil,
queue: .main) { [unowned self] (notification) in
guard let confirmation = notification.object as PaymentConfirmation else { return }
self.paymentProcessed(confirmation)
}
}
deinit {
NotificationCenter.default.removeObserver(paymentProcessedObserver)
}
func paymentProcessed(_ confirmation: PaymentConfirmation) {
// do stuff
}
Then in your AppDelegate:
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any]) -> Bool {
// do stuff required with the callback URL
let confirmation = PaymentConfirmation(
amount: 3.0,
confirmationNumber: "Pay830da08.8380zSomething")
NotificationCenter.default.post(
name: PayView.paymentProcessedNotification,
object: confirmation)
}
For more information, check out https://medium.com/ios-os-x-development/broadcasting-with-nsnotification-center-8bc0ccd2f5c3
Upvotes: 2