2013-07-15 44 views
-1

我有一個問題,我不知道如何解決它。Objective-C在其他方法中使用NSString

Viewcontroller.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到viewDidLoad中在後deviceTokenString但它不會工作。

當我在ViewController.h有這樣的代碼

@interface ViewController : UIViewController { 
NSString *deviceTokenString; 
} 

@property(nonatomic, retain) NSString *deviceTokenString; 

它只返回「空」,而不是deviceToken

我希望有人能幫助我:)

回答

1

你正在處理兩個不同的類,你的UIApplication的委託類和一個UIViewController類。默認情況下,一個類中定義的實例變量不會暴露給其他類,除非它們也被定義爲該類的屬性。

就你而言,你已經在你的deviceTokenString對象的View Controller類上定義了一個屬性。因此,您已經將View Controller的這個屬性暴露給其他可能有興趣訪問此對象的類。

在您的UIApplicationDelegate對象的didReceiveRemote...方法中,NSString對象由系統傳入,參數名稱爲deviceToken。當你收到這個對象時,你不需要做任何其他操作(即stringWithFormat:)。

你在應用程序中可能遇到或可能不會遇到的情況就是所謂的競爭條件。 viewDidLoad可能在您的應用收到didReceiveToken消息之前發生。對此謹慎。

解決你的問題,你應該做的是訪問您的viewController對象在didReceiveRemote...方法,像這樣:

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

並不是說這是爲了做到這一點的最好辦法,但它會解決你的問題。還會留下其他內容,例如設置屬性時發生的情況。在viewDidLoad中做它是一種自動執行操作的簡單方法。解決這個問題的方法是使用Key-Value-Observing,這是另一個問題/教程本身。

GOOD運氣。

0

你重新聲明的NSString deviceTokenString在 - (void)應用程序函數中。該本地聲明取代了界面中聲明的屬性。因此,當該應用程序函數超出範圍時,您創建的NSString對象(位於堆棧中)不再存在。

從取出的NSString * - (空)應用功能

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

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

這應該可以解決您的問題

+0

對於任何最新版本的iOS SDK,綜合將不是必需的。 –

+0

好吧,很高興知道。編輯和刪除 –

+0

首先,感謝您的反應,但不幸的是它仍然顯示「空」.. –

1

它只返回 「空」,而不是deviceToken

這是因爲你已經聲明瞭一個與你的實例變量同名的局部變量。在-application:didRegisterForRemoteNotificationsWithDeviceToken:你有:

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

它創建了一個名爲deviceTokenString一個局部變量。該方法一退出,該變量就會消失。你從不設置實例變量,所以當你嘗試訪問-viewDidLoad時,你會得到零。

要解決此問題,只需更改上面的一行:

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

現在你正在使用的deviceTokenString這是你的實例變量,因此該值將被分配到伊娃並會持續超越方法結束。

+0

首先,感謝您的反應,但不幸的是它仍然顯示「空」.. –

+0

@HenkdeBoer對不起 - 我寫了一個有點太快了。賈斯汀的解釋也是如此;他是對的,你是(或者應該)談論兩個不同的課程。 '-application:didRegisterForRemoteNotificationsWithDeviceToken:'是一個應用程序委託方法,而'-viewDidLoad'是一個視圖控制器方法。單個對象通常不能同時作爲應用程序委託和視圖控制器。因此,您可能希望讓應用程序委託向視圖控制器發送帶有字符串的消息或(不太好)讓視圖控制器嚮應用程序委託請求該字符串。 – Caleb