草庐IT

ios - 从通知打开应用程序时打开特定 View

coder 2023-07-25 原文

我刚刚向我的应用添加了推送通知。我想要这样当用户从通知打开应用程序时,它将打开一个特定的 View Controller 而不是我的 rootViewController。这是我的 AppDelegate:

#import "KFBAppDelegate.h"
#import "KFBViewController.h"
#import "AboutUs.h"
#import "ContactUs.h"
#import "KYFB.h"
#import "KFBNavControllerViewController.h"
#import "KFBTabBarViewController.h"
#import "RSFM.h"
#import "LegislatorInfo.h"
#import "Events.h"
#import "ActionAlertsViewController.h"
#import "UAirship.h"
#import "UAPush.h"
#import "UAAnalytics.h"

@implementation KFBAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // This prevents the UA Library from registering with UIApplcation by default when
    // registerForRemoteNotifications is called. This will allow you to prompt your
    // users at a later time. This gives your app the opportunity to explain the benefits
    // of push or allows users to turn it on explicitly in a settings screen.
    // If you just want everyone to immediately be prompted for push, you can
    // leave this line out.
    // [UAPush setDefaultPushEnabledValue:NO];

    //Create Airship options dictionary and add the required UIApplication launchOptions
    NSMutableDictionary *takeOffOptions = [NSMutableDictionary dictionary];
    [takeOffOptions setValue:launchOptions forKey:UAirshipTakeOffOptionsLaunchOptionsKey];

    // Call takeOff (which creates the UAirship singleton), passing in the launch options so the
    // library can properly record when the app is launched from a push notification. This call is
    // required.
    //
    // Populate AirshipConfig.plist with your app's info from https://go.urbanairship.com
    [UAirship takeOff:takeOffOptions];

    // Set the icon badge to zero on startup (optional)
    [[UAPush shared] resetBadge];

    // Register for remote notfications with the UA Library. This call is required.
    [[UAPush shared] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
                                                         UIRemoteNotificationTypeSound |
                                                         UIRemoteNotificationTypeAlert)];

    // Handle any incoming incoming push notifications.
    // This will invoke `handleBackgroundNotification` on your UAPushNotificationDelegate.
    [[UAPush shared] handleNotification:[launchOptions valueForKey:UIApplicationLaunchOptionsRemoteNotificationKey]
                       applicationState:application.applicationState];

    // self.tabBarController = [[UITabBarController alloc] initWithNibName:@"KFBViewController" bundle:nil];
    KFBViewController *rootView = [[KFBViewController alloc] initWithNibName:@"KFBViewController" bundle:nil];
    KFBNavControllerViewController *navController = [[KFBNavControllerViewController alloc] initWithRootViewController:rootView];
    navController.delegate = rootView;
    UIViewController *aboutUs = [[AboutUs alloc] initWithNibName:@"AboutUs" bundle:nil];

    KFBNavControllerViewController *navController1 = [[KFBNavControllerViewController alloc] initWithRootViewController:aboutUs];


    UIViewController *contactUs = [[ContactUs alloc] initWithNibName:@"ContactUs" bundle:nil];
    KFBNavControllerViewController *navController2 = [[KFBNavControllerViewController alloc] initWithRootViewController:contactUs];
    UIViewController *kyfb = [[KYFB alloc] initWithNibName:@"KYFB" bundle:nil];

    KFBNavControllerViewController *navController3 = [[KFBNavControllerViewController alloc] initWithRootViewController:kyfb];

    // UIViewController *rsfm = [[RSFM alloc] initWithNibName:@"RSFM" bundle:nil];
    // KFBNavControllerViewController *navController4 = [[KFBNavControllerViewController alloc] initWithRootViewController:rsfm];

    // UIViewController *li = [[LegislatorInfo alloc] initWithNibName:@"LegislatorInfo" bundle:nil];
    // KFBNavControllerViewController *navController5 = [[KFBNavControllerViewController alloc] initWithRootViewController:li];

    // UIViewController *events = [[Events alloc] initWithNibName:@"Events" bundle:nil];
    // KFBNavControllerViewController *navController6 = [[KFBNavControllerViewController alloc] initWithRootViewController:events];
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    //self.viewController = [[KFBViewController alloc] initWithNibName:@"KFBViewController" bundle:nil];
    //self.window.rootViewController = self.viewController;
    self.tabBarController = [[KFBTabBarViewController alloc] init];
    self.tabBarController.viewControllers = @[navController, navController1, navController2, navController3];
    // self.tabBarController.customizableViewControllers = nil;

    self.window.rootViewController = self.tabBarController;
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];

    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application
{
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // 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.
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    UA_LDEBUG(@"Application did become active.");

    // Set the icon badge to zero on resume (optional)
    [[UAPush shared] resetBadge];
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    [UAirship land];
}

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    // Updates the device token and registers the token with UA.
    [[UAPush shared] registerDeviceToken:deviceToken];
}

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *) error
{
    UA_LERR(@"Failed To Register For Remote Notifications With Error: %@", error);
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{

    UA_LINFO(@"Received remote notification: %@", userInfo);

    // Send the alert to UA so that it can be handled and tracked as a direct response. This call
    // is required.
    [[UAPush shared] handleNotification:userInfo applicationState:application.applicationState];

    // Optionally provide a delegate that will be used to handle notifications received while the app is running
    // [UAPush shared].delegate = your custom push delegate class conforming to the UAPushNotificationDelegate protocol

    // Reset the badge after a push received (optional)
    [[UAPush shared] resetBadge];
}

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    return UIInterfaceOrientationMaskAllButUpsideDown;
}

@end

这是我想在打开通知时打开的 View Controller :

#import "ActionAlertsViewController.h"
#import "RSSChannel.h"
#import "RSSItem.h"
#import "WebViewController.h"
#import "CustomCellBackground.h"

@implementation ActionAlertsViewController
{
    UIActivityIndicatorView *loadingIndicator;
}
@synthesize webViewController;

- (void)viewDidLoad
{
    self.tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];
    self.title = @"Action Alerts";
    loadingIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
    loadingIndicator.center = CGPointMake(160, 160);
    loadingIndicator.hidesWhenStopped = YES;
    [self.view addSubview:loadingIndicator];
    [loadingIndicator startAnimating];
    // UIRefreshControl *refresh = [[UIRefreshControl alloc] init];
    // refresh.attributedTitle = [[NSAttributedString alloc] initWithString:@"Pull to Refresh"];
    // [refresh addTarget:self action:@selector(refreshView:)forControlEvents:UIControlEventValueChanged];
    // self.refreshControl = refresh;
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    NSLog(@"%@ found a %@ element", self, elementName);
    if ([elementName isEqual:@"channel"])
    {
        // If the parser saw a channel, create new instance, store in our ivar
        channel = [[RSSChannel alloc]init];

        // Give the channel object a pointer back to ourselves for later
        [channel setParentParserDelegate:self];

        // Set the parser's delegate to the channel object
        [parser setDelegate:channel];
    }
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // return 0;
    NSLog(@"channel items %d", [[channel items]count]);
    return [[channel items]count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // return nil;

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"];
    if (cell == nil)
    {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"UITableViewCell"];
        cell.textLabel.font=[UIFont systemFontOfSize:16.0];
    }
    RSSItem *item = [[channel items]objectAtIndex:[indexPath row]];
    [[cell textLabel]setText:[item title]];
    cell.backgroundView = [[CustomCellBackground alloc] init];
    cell.selectedBackgroundView = [[CustomCellBackground alloc] init];
    cell.textLabel.backgroundColor = [UIColor clearColor];
    cell.textLabel.highlightedTextColor = [UIColor darkGrayColor];

    return cell;
}

- (void)fetchEntries
{
    // Create a new data container for the stuff that comes back from the service
    xmlData = [[NSMutableData alloc]init];

    // Construct a URL that will ask the service for what you want -
    // note we can concatenate literal strings together on multiple lines in this way - this results in a single NSString instance
    NSURL *url = [NSURL URLWithString:@"http://kyfbnewsroom.com/category/public-affairs/notifications/feed/"];

    // Put that URL into an NSURLRequest
    NSURLRequest *req = [NSURLRequest requestWithURL:url];

    // Create a connection that will exchange this request for data from the URL
    connection = [[NSURLConnection alloc]initWithRequest:req delegate:self startImmediately:YES];
}

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];

    if (self)
    {
        [self fetchEntries];
    }

    return self;
}

// This method will be called several times as the data arrives
- (void)connection:(NSURLConnection *)conn didReceiveData:(NSData *)data
{
    // Add the incoming chunk of data to the container we are keeping
    // The data always comes in the correct order
    [xmlData appendData:data];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)conn
{
    /* We are just checking to make sure we are getting the XML
     NSString *xmlCheck = [[NSString alloc]initWithData:xmlData encoding:NSUTF8StringEncoding];
     NSLog(@"xmlCheck = %@", xmlCheck);*/

    [loadingIndicator stopAnimating];

    // Create the parser object with the data received from the web service
    NSXMLParser *parser = [[NSXMLParser alloc]initWithData:xmlData];

    // Give it a delegate - ignore the warning here for now
    [parser setDelegate:self];

    //Tell it to start parsing - the document will be parsed and the delegate of NSXMLParser will get all of its delegate messages sent to it before this line finishes execution - it is blocking
    [parser parse];

    // Get rid of the XML data as we no longer need it
    xmlData = nil;

    // Reload the table.. for now, the table will be empty
    NSMutableArray *notActionAlerts = [NSMutableArray array];
    for (RSSItem *object in channel.items) {
        if (!object.isActionAlert) {
            [notActionAlerts addObject:object];
        }
    }

    for (RSSItem *object in notActionAlerts) {
        [channel.items removeObject:object];
    }

    [[self tableView]reloadData];

    NSLog(@"%@\n %@\n %@\n", channel, [channel title], [channel infoString]);
}

- (void)connection:(NSURLConnection *)conn didFailWithError:(NSError *)error
{
    // Release the connection object, we're done with it
    connection = nil;

    // Release the xmlData object, we're done with it
    xmlData = nil;

    // Grab the description of the error object passed to us
    NSString *errorString = [NSString stringWithFormat:@"Fetch failed: %@", [error localizedDescription]];

    // Create and show an alert view with this error displayed
    UIAlertView *av = [[UIAlertView alloc]initWithTitle:@"Error" message:errorString delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [av show];
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Push the web view controller onto the navigation stack - this implicitly creates the web view controller's view the first time through
    // [[self navigationController]pushViewController:webViewController animated:YES];
    [self.navigationController pushViewController:webViewController animated:NO];

    // Grab the selected item
    RSSItem *entry = [[channel items]objectAtIndex:[indexPath row]];

    // Construct a URL with the link string of the item
    NSURL *url = [NSURL URLWithString:[entry link]];

    // Construct a request object with that URL
    NSURLRequest *req = [NSURLRequest requestWithURL:url];

    // Load the request into the web view
    [[webViewController webView]loadRequest:req];
    webViewController.hackyURL = url;
    // Set the title of the web view controller's navigation item
    // [[webViewController navigationItem]setTitle:[entry title]];
}

/*
 -(void)refreshView:(UIRefreshControl *)refresh
{
    refresh.attributedTitle = [[NSAttributedString alloc] initWithString:@"Refreshing data..."];

    // custom refresh logic would be placed here...

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"MMM d, h:mm a"];
    NSString *lastUpdated = [NSString stringWithFormat:@"Last updated on %@",[formatter stringFromDate:[NSDate date]]];
    refresh.attributedTitle = [[NSAttributedString alloc] initWithString:lastUpdated];
    [refresh endRefreshing];
}
*/

@end

这是我添加到 didFinishLaunchingWithOptions 方法中的代码块。我几乎一切正常。选择一行时,Web View 现在可以工作,并且导航栏在那里并且看起来可以正常工作。我现在遇到的唯一麻烦是让标签栏显示出来。这是我目前正在使用的代码块。

UILocalNotification *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];

    if (notification)
    {
        ActionAlertsViewController *actionAlerts = [[ActionAlertsViewController alloc] initWithStyle:UITableViewStylePlain];
        WebViewController *wvc = [[WebViewController alloc]init];
        [actionAlerts setWebViewController:wvc];
        KFBNavControllerViewController *navController7 = [[KFBNavControllerViewController alloc] initWithRootViewController:actionAlerts];
        [self.window.rootViewController presentViewController:navController7 animated:NO completion:nil];
    }

最佳答案

您可以在收到远程通知时自己发布通知,并通过将 View Controller 注册到此通知,您可以在收到通知后打开特定的 View Controller 。

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{

   [[NSNotificationCenter defaultCenter] postNotificationName:@"pushNotification" object:nil userInfo:userInfo];

}

在您的 FirstViewController.m 中注册收听此通知。

-(void)viewDidLoad{  

      [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pushNotificationReceived) name:@"pushNotification" object:nil];

}

在方法中你可以打开特定的viewController

-(void)pushNotificationReceived{

 [self presentViewController:self.secondViewController animated:YES completion:nil];
}

最后在 dealloc 方法中取消注册当前 viewController 的通知

-(void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self];

}

关于ios - 从通知打开应用程序时打开特定 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15501500/

有关ios - 从通知打开应用程序时打开特定 View的更多相关文章

  1. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  2. ruby - 将差异补丁应用于字符串/文件 - 2

    对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl

  3. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  4. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  5. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  6. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  7. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

  8. ruby - 在 Ruby 中编写命令行实用程序 - 2

    我想用ruby​​编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序

  9. ruby-on-rails - Rails 应用程序之间的通信 - 2

    我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

  10. ruby - 无法运行 Rails 2.x 应用程序 - 2

    我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby​​:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r

随机推荐