-1

我有一个问题,我不知道如何解决它。

视图控制器.m

-(void)application:(UIApplication *)application     didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSLog(@"APN device token: %@", deviceToken);
NSString *deviceTokenString = [NSString stringWithFormat:@"%@",deviceToken];
}

- (void)viewDidLoad
{
NSMutableURLRequest *request =[NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.domain.com/blabla.php"]];
[request setHTTPMethod:@"POST"];

NSString *post =[[NSString alloc] initWithFormat:@"udid=%@&submit=",deviceTokenString];
[request setHTTPBody:[post dataUsingEncoding:NSUTF8StringEncoding]];

NSURLResponse *response;
NSError *err;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];

[super viewDidLoad];
}

我希望应用程序 didRegisterForRemoteNotificationsWithDeviceToken 中的 deviceTokenString 到帖子中的 viewDidLoad 但它不起作用。

当我在 ViewController.h 中有这段代码时

@interface ViewController : UIViewController {
NSString *deviceTokenString;
}

@property(nonatomic, retain) NSString *deviceTokenString;

它只返回“Null”而不是 deviceToken

我希望有一个人可以帮助我 :)

4

3 回答 3

1

it only returns "Null" and not the deviceToken

That's because you've declared a local variable with the same name as your instance variable. In -application:didRegisterForRemoteNotificationsWithDeviceToken: you've got:

NSString *deviceTokenString = [NSString stringWithFormat:@"%@",deviceToken];

which creates a local variable named deviceTokenString. That variable goes away as soon as the method exits. You never set the instance variable, so when you try to access that in -viewDidLoad you get nil.

To fix the problem, simply change the line above to:

deviceTokenString = [NSString stringWithFormat:@"%@",deviceToken];

Now you're using the deviceTokenString that is your instance variable, so the value will be assigned to the ivar and will persist beyond the end of the method.

于 2013-07-15T20:49:37.927 回答
1

您正在处理两个不同的类,您的 UIApplication 的委托类和 UIViewController 类。默认情况下,一个类中定义的实例变量不会暴露给其他类,除非它们也被定义为该类的属性。

在您的情况下,您已经在 View Controller 类上为您的deviceTokenString对象定义了一个属性。因此,您已将 View Controller 的此属性公开给可能对访问此对象感兴趣的其他类。

在您的 UIApplicationDelegate 对象中,在didReceiveRemote...方法中,系统会使用参数 name 为您传入一个 NSString 对象deviceToken。当您收到此对象时,您无需对其进行任何其他操作(即stringWithFormat:)。

您在应用程序中可能会或可能不会遇到的东西称为竞态条件。viewDidLoad可能在您的应用收到didReceiveToken消息之前发生。警惕这一点。

要解决您的问题,您应该做的是在didReceiveRemote...方法中访问您的 viewController 对象,如下所示:

-(void)didReceiveToken... {
      UIViewController *myViewController = self.viewController; //how do you initially set up this object?
      myViewController.deviceTokenString = deviceToken;
}

并不是说这是最好的方法,但它会解决你的问题。也忽略了其他事情,比如设置属性时会发生什么。在 viewDidLoad 中执行此操作是一种自动执行操作的简单方法。解决此问题的一种方法是使用 Key-Value-Observing,这本身就是另一个问题/教程。

祝你好运。

于 2013-07-15T21:00:04.300 回答
0

您正在 -(void)application 函数中重新声明 NSString deviceTokenString。该本地声明取代了接口中声明的属性。因此,当该应用程序函数超出范围时,您创建的 NSString 对象(在堆栈上)将不再存在。

从 -(void)application 函数中删除 NSString *

-(void)application:(UIApplication *)application    
    didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {

      NSLog(@"APN device token: %@", deviceToken);
      deviceTokenString = [NSString stringWithFormat:@"%@",deviceToken];
}

这应该可以解决您的问题

于 2013-07-15T20:46:57.473 回答