I have a small problem.
I try for a push notification to control a View Controller.
I come to go there, however, the new "page" not open.
If I send forth the same but with an action button it works.
Thank you, Chris
AppDelegate.m
RootViewController *rootViewController = (RootViewController*)self.window.rootViewController;
[rootViewController openLinkNews];
RootViewController.m
- (void)awakeFromNib {
self.contentViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"contentController"];
self.menuViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"menuController"];
}
-(void)openLinkNews {
NewsTab *theLink = [[NewsTab alloc] init];
[theLink openNewsPerLink];
}
NewsTab.m
-(void)openNewsPerLink{
NSLog(#"You are here!");
dbConnect = [[DbConnect alloc] init];
getNewsLast = [dbConnect getNewsLast];
DbConnect *news = [getNewsLast objectAtIndex:0];
NewsTab * infoController = [self.storyboard instantiateViewControllerWithIdentifier:#"NewsOpenViewController"];
NewsOpen *detailViewController = (NewsOpen *) infoController;
detailViewController.NewsHeadline = news.NewsHeadline;
detailViewController.NewsInformation = news.NewsInformation;
detailViewController.NewsFrom = news.NewsFrom;
detailViewController.NewsDate = news.NewsDate;
[self.navigationController pushViewController:infoController animated:YES];
}
-(IBAction)ButtonTest:(id)sender {
[self openNewsPerLink];
}
You posted code from your app delegate, but what method is that in?
The app delegate can retrieve information about the notification and respond to it in its - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo method. From there you you can do whatever you wish and use the notification to inform your decisions.
Please see the UIApplicationDelegate protocol reference
Related
I'm looking through the code, specifically the Main View Controller that initiates calls with the call button. Both users must be on this View Controller after inputting their names to be found in a database.
But I'm confused as to how the callee is notified of a call and how it segues into a Calling View Controller that shows that they can answer or hangup.
I know that prepareForSegue sets the call to be whoever called, but I'm still confused with the remaining few lines after that.
So note the last two delegate methods: the first delegate method performs a segue, which makes sense. But what about the second one because I'm confused as to how it segues into call view controller that lets the callee answer or decline.
MainViewController.m
#import "MainViewController.h"
#import "CallViewController.h"
#import <Sinch/Sinch.h>
#interface MainViewController () <SINCallClientDelegate>
#end
#implementation MainViewController
- (id<SINClient>)client {
return [(AppDelegate *)[[UIApplication sharedApplication] delegate] client];
}
- (void)awakeFromNib {
self.client.callClient.delegate = self;
}
- (IBAction)call:(id)sender {
if ([self.destination.text length] > 0 && [self.client isStarted]) {
id<SINCall> call = [self.client.callClient callUserWithId:self.destination.text];
[self performSegueWithIdentifier:#"callView" sender:call];
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
CallViewController *callViewController = [segue destinationViewController];
callViewController.call = sender;
}
#pragma mark - SINCallClientDelegate
// Outgoing Call?
- (void)client:(id<SINCallClient>)client didReceiveIncomingCall:(id<SINCall>)call {
[self performSegueWithIdentifier:#"callView" sender:call];
}
// Incoming Call?
- (SINLocalNotification *)client:(id<SINClient>)client localNotificationForIncomingCall:(id<SINCall>)call {
SINLocalNotification *notification = [[SINLocalNotification alloc] init];
notification.alertAction = #"Answer";
notification.alertBody = [NSString stringWithFormat:#"Incoming call from %#", [call remoteUserId]];
return notification;
}
(void)client:(id)client didReceiveIncomingCall:(id)call {
[self performSegueWithIdentifier:#"callView" sender:call];
}
is called when the app is in the foreground and an incoming call is in prgress, it will push the viewcontroller with teh call and since its direction is incoming you will be presented with an answer decline button,
(SINLocalNotification *)client:(id)client localNotificationForIncomingCall:(id)call {
SINLocalNotification *notification = [[SINLocalNotification alloc] init];
notification.alertAction = #"Answer";
notification.alertBody = [NSString stringWithFormat:#"Incoming call from %#", [call remoteUserId]];
return notification;
}
is called when the app is the background and you have enabled push
But what about the second one because I'm confused as to how it segues into call view controller that lets the callee answer or decline
The header explains to you what happens:
The return value will be used by SINCallClient to schedule ... a UILocalNotification. That UILocalNotification, when triggered and taken action upon by the user, is supposed to be used in conjunction with
-[SINClient relayLocalNotification:].
Before I begin, I have searched Stackoverflow for how to do this, and I saw a lot of related posts, but none worked for me and I'm not sure why.
So basically I have a loginViewController, and in it, I have a method that call's GoogleSignIn:
- (void)googleTap:(id)sender
{
[[GIDSignIn sharedInstance] signIn];
}
Now the way GoogleSignIn is set up, the result of that sign in call is handled inside AppDelegate.m
- (void)signIn:(GIDSignIn *)signIn
didSignInForUser:(GIDGoogleUser *)user
withError:(NSError *)error {
// Perform any operations on signed in user here.
if (!error) {
NSString *userId = user.userID; // For client-side use only!
NSString *idToken = user.authentication.idToken; // Safe to send to the server
NSString *name = user.profile.name;
NSString *email = user.profile.email;
NSLog(#"Name: %#, User: %#, Token: %#, Email: %#",name, userId, idToken, email);
// ...
}
}
Inside this AppDelegate method, I want to call a method from my loginViewController:
-(void)onSuccessfulLogin{
NSLog(#"On Successful Login");
[self.navigationController pushViewController:[collectionViewController new] animated:YES];
}
I tried these answers: Calling UIViewController method from app delegate
want to call ViewController's method from appdelegate
and the NSLog is called, but the new ViewController is never pushed...why is that and how can I get that to work?
If this is your app delegate you have no self.navigationController. You probably changed the name of your NavigationController to something like UINavigationController *navigationController = [[UINavigationController alloc] init] You need to set a #property for a nav controller on the delegate class. Then where you initialize the nav controller
UINavigationController *navigationController = [[UINavigationController alloc] init]`
self.navigationController = navigationController// You need this line.
//In your method
[self.navigationController pushViewController:[collectionViewController new] animated:YES];
Declare your onSuccessfulLogin method in YourViewController.h (header file)
In (void)signIn:didSignInForUser:withError: method, put below code at bottom
if ([self.navigationController.viewControllers.lastObject respondsToSelector:#selector(onSuccessfulLogin)]) {
[((YourViewController *)self.navigationController.viewControllers.lastObject) onSuccessfulLogin];
}
I was thinking about this wrong all along. You can move the GDSignInDelegate from AppDelegate to viewcontroller.h.
Then you can simply move the -(void)signIn: didSignInUser: method to your ViewController. And you can call your method from there!
I am a newbee in iOS development and recently run into this problem with customized transition in iOS 9.
I have an object conforms to UIViewControllerTransitioningDelegate protocol and implements animationControllerForDismissedController, something like:
#implementation MyCustomizedTransitioningDelegate
#pragma mark - UIViewControllerTransitioningDelegate
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
{
MyCustomizedTransitionAnimator *animator = [[MyCustomizedTransitionAnimator alloc] init];
animator.presenting = NO;
return animator;
}
#end
And the process that triggers the modal transition is something like:
#implementation MyViewController
#pragma mark - Initializers
+ (MyCustomizedTransitioningDelegate *)modalTransitioningDelegateSingletonInstance;
{
static MyCustomizedTransitioningDelegate *delegateInst = nil;
static dispatch_once_t onceToken = 0;
dispatch_once(&onceToken, ^{
delegateInst = [[MyCustomizedTransitioningDelegate alloc] init];
});
return delegateInst;
}
#pragma mark - UIViewController
- (void)dismissViewControllerAnimated:(BOOL)animated completion:(void (^)(void))completion;
{
[self prepareForDismissViewControllerAnimated:animated completion:&completion];
[super dismissViewControllerAnimated:animated completion:completion];
}
- (void)prepareForDismissViewControllerAnimated:(BOOL)animated completion:(dispatch_block_t *)completion;
{
self.presentedViewController.modalPresentationStyle = UIModalPresentationCustom;
self.presentedViewController.transitioningDelegate = [[self class] modalTransitioningDelegateSingletonInstance];
}
#end
Since animationControllerForDismissedController method is not called, the MyCustomizedTransitionAnimator is not created, which leads to its animateTransition not called either, which causes unexpected problem in my app. (Sorry for my poor English...)
I am also attaching the screenshot of stack trace for both iOS8 & iOS9.
In iOS 8, animationControllerForDismissedController is called after the stack trace below.
But in iOS9, transitionDidFinish is called somehow in advance, which I guess probably prevent animationControllerForDismissedController being called?
I was wondering if this is an iOS 9 bug or not. Any explanation or work around solution will be greatly appreciated!
I faced the same issue.
I hope this will help someone.
What fixed it for me is to make the object which applies UIViewControllerTransitioningDelegate protocol as variable instance to keep strong relationship with it.
I think because it gets dismissed after the view is presented first time.
I had the same issue.
Turned out I needed to set the delegate on the navigationController of the UIViewController that contains the trigger button.
Having this old code that didn't work:
UIViewController *dvc = [self sourceViewController];
TransitionDelegate *transitionDelegate = [TransitionDelegate new];
dvc.modalPresentationStyle = UIModalPresentationCustom;
dvc.transitioningDelegate = transitionDelegate;
[dvc dismissViewControllerAnimated:YES completion:nil];
I changed the first line to:
UIViewController *dvc = [self sourceViewController].navigationController;
and it worked.
Hope this helps.
You need to say something like:
MyDestinationViewController *viewController = [[MyDestinationViewController alloc] init];
MyCustomizedTransitioningDelegate *transitioningDelegate = [[MyCustomizedTransitioningDelegate alloc]init];
viewController.transitioningDelegate = transitioningDelegate;
viewController.modalPresentationStyle = UIModalPresentationCustom;
[self presentViewController: viewController animated:YES completion:nil];
Or if you're using segues, in prepareForSegue say something like:
MyDestinationViewController *toVC = segue.destinationViewController;
MyCustomizedTransitioningDelegate *transitioningDelegate = [[MyCustomizedTransitioningDelegate alloc]init];
toVC.transitioningDelegate = transitioningDelegate;
I would like to learn how to do an functional block of views.
For example:
I've got a book's list and I want to add a book with a button.
When I push the button --> Launch a Storyboard that it have a navigation controller with 2 or more views. (this create the Book object) and return it to the tableView.
The first table view will receive an object (Book) anymore.
Now, I used a view controller with:
+ (AddBookViewController *)sharedInstance {
static dispatch_once_t once;
static AddBookViewController * sharedInstance;
dispatch_once(&once, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
- (id)init {
self = [super init];
if(self != nil) {
self = (AddBookViewController *)[[UIStoryboard storyboardWithName:#"AddBook" bundle:nil] instantiateInitialViewController];
}
return self;
}
- (void)showAddBookVCInController:(UIViewController *)hostVC completion:(AddBookCompletionHandler)completionHandler
{
self.compHandler =[completionHandler copy];
UINavigationController * navCtrl = [[UINavigationController alloc]initWithRootViewController:self];
//Show view!
[hostVC presentViewController:navCtrl animated:YES completion:^{
[self.tableView reloadData];
}];
Any idea or tutorial for this?
Thanks!
Sorry my bad english...
-(void)bookChosen:(Book *)bookObject
{
NSDictionary* userInfo = #{#"BOOK_KEY": #(bookObject)};
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
[nc postNotificationName:#"kBookChosenNotification" object:self userInfo:userInfo];
//here you will write pop if it is Navigation controller flow of presenting view
// OR
//here you will write dismissViewController.... if it was presented using flow of presenting view
}
in the view controller where you have list of fav books:
add this in viewDidLoad:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(receivedChosenBookNotification:) name:#"kBookChosenNotification" object:nil];
and implement method receivedChosenBookNotification like below
-(void) receivedChosenBookNotification:(NSNotification*)notification
{
if ([notification.name isEqualToString:#"kBookChosenNotification"])
{
NSDictionary* userInfo = notification.userInfo;
Book* bookObject = userInfo[#"BOOK_KEY"];
NSLog (#"Successfully received chosen book %#", bookObject);
}
}
i am not able to understand what you want to do after choosing book, i mean you want to dismiss or you want to pop. It depends on your flow of presenting/pushing view A >> B >>C. Its upto you but in any case you will be able to receive a book object in view controller A (or say it where you have list of fav books). Hope it helps
I want to reset my UISearch when app is entering background, or entering foreground again. It would be enough when the tableview from UISearch gets hidden.
But when I try to hide it from AppDelegate.m it doesn't work. I have also logged the UIElements, there are also (null).
Here is how I try to access it:
- (void)applicationWillEnterForeground:(UIApplication *)application
{
XLog(#"");
/*
Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
*/
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
XLog(#"");
searchViewController = [[SearchViewController alloc] initWithNibName:#"SearchViewController_iPad" bundle:[NSBundle mainBundle]];
} else {
XLog(#"");
searchViewController = [[SearchViewController alloc] initWithNibName:#"SearchViewController_iPhone" bundle:[NSBundle mainBundle]];
}
XLog(#"searchViewController.searchBar.text: %#", searchViewController.searchBar.text);
searchViewController.tableViewSearch.hidden = YES; // is (null)
XLog(#"searchViewController.tableViewSearch: %#", searchViewController.tableViewSearch); // is (null)
}
How can I access that? Do I something wrong here, or is it not allowed to access elements from other classes thru appdelegate.m?
NSArray *ary_navigationControllerViews = [[NSArray alloc] initWithArray:[self.navigationController viewControllers]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"self.class.description == %#", [[SearchViewController class] description]];
NSArray *ary_viewController = [[NSArray alloc] initWithArray:[ary_navigationControllerViews filteredArrayUsingPredicate:predicate]];
if ([ary_viewController count] > 0)
{
SearchViewController *sVw = (SearchViewController*) [ary_viewController objectAtIndex:0] ;
sVw.tableViewSearch.hidden = YES;
}
You are initializing new instance of your view controller, instead you need to get existing instance of your view controller and hide your view. Hope this helps.