0

我有tableview,其中是名稱和狀態。蘋果推送通知(APNS)時狀態發生變化。 但我有這個問題。如果通知未到,我該怎麼辦?或者如果用戶點擊此消息的關閉按鈕。 我嘗試使用ASIHTTPRequest更新表:從webserver(ASIHTTPRequest,PHP,mysql)更新iOS TableView單元格中的數據

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"Cell"; 
    HomePageTableCell *cell = (HomePageTableCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; 

    // Configure the cell... 
    NSManagedObject *device = [self.devices objectAtIndex:indexPath.row]; 
    cell.nameLabel.text = [device valueForKey:@"name"]; 

    if ([[device valueForKey:@"status"] isEqualToNumber:@1]) 
    { 
     cell.status.text = @"Not configured"; 
     cell.stav.image = [UIImage imageNamed:@"not_configured.png"]; 
    } 
    if ([[device valueForKey:@"status"] isEqualToNumber:@2]) 
    { 
     //some other states 
    } 

    return cell; 
} 

我嘗試這種改變小區之前的狀態是載入中...

- (void) getStatus:(NSString *)serialNumber 
{ 
    NSURL *url = [NSURL URLWithString:@"link to my server"]; 

    __block ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url]; 
    __weak ASIHTTPRequest *request_b = request; 
    request.delegate = self; 

    [request setPostValue:@"updatedevice" forKey:@"cmd"]; 
    [request setPostValue:serialNumber forKey:@"serial_number"]; //get status of this serial number 

    [request setCompletionBlock:^ 
    { 
     if([self isViewLoaded]) 
     { 
      [MBProgressHUD hideHUDForView:self.view animated:YES]; 
      if([request_b responseStatusCode] != 200) 
      { 
       ShowErrorAlert(@"Comunication error", @"There was an error communicating with the server");      
      } 
      else 
      {          
       NSString *responseString = [request_b responseString]; 
       SBJsonParser *parser = [[SBJsonParser alloc] init]; 
       NSDictionary *result = [parser objectWithString:responseString error:nil]; 

       status = [result objectForKey:@"status"]; 
       NSInteger statusInt = [status intValue]; //change to int value 

       //here I want to change cell status in SQLite, but don't know how 
       //something with indexPath.row? valueForKey:@"status"???     
      } 
     } 
    }]; 
    [request setFailedBlock:^ 
    { 
     if ([self isViewLoaded]) 
     { 
      [MBProgressHUD hideHUDForView:self.view animated:YES]; 
      ShowErrorAlert(@"Error", [[request_b error] localizedDescription]); 

     } 
    }]; 

    [request startAsynchronous]; 
} 

或者是更好的方式來改變我的表視圖,如果狀態蘋果通知沒有來或用戶沒有點擊通知消息?謝謝

編輯: 我不知道如何將數據存儲到NSManagedObject *設備。你能幫助我嗎? 我試試這個,但它沒有工作:(你在哪裏寫的地方)

NSInteger statusInt = [status intValue]; //change to int value 
NSManagedObject *device = [self.devices objectAtIndex:indexPath.row]; 
[device setValue:statusInt forKey:@"status"]; 

EDIT2: 我得到它,但問題是重裝表數據

NSString *responseString = [request_b responseString]; 
SBJsonParser *parser = [[SBJsonParser alloc] init]; 
NSDictionary *result = [parser objectWithString:responseString error:nil]; 

NSString *status = [result objectForKey:@"status"]; 
NSInteger statusInt = [status intValue]; //change to int value 
NSManagedObject *device = [self.devices objectAtIndex:indexPath.row]; 
[device setValue:statusInt forKey:@"status"]; //there is problem in save statusInt 

// [設備setValue:@ 5 forKey:@「status」]; //如果我這樣做沒關係狀態是integer16型

第二個問題是在重裝表數據。我把它放在這裏

[self.tableView reloadData] 

但它在循環中一遍又一遍地重新加載,有什麼錯?我的事情有無限循環,如果我沒有重新加載表格數據的變化將在下一個應用程序加載可見。我認爲問題是,我稱之爲

- (void) getStatus:(NSString *)serialNumber atIndexPath:(NSIndexPath *)indexPath 
{} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
} 

更好的應該是在viewDidLoad中或viewDidApper,但我不知道該怎麼做迴路所有設備和呼叫

[self getStatus:[device valueForKey:@"serialNumber"] atIndexPath:indexPath]; 

在那個地方。

EDIT3:

,如果我不喜歡這樣寫道:

- (void)viewDidLoad 
{ 
    [self updateData]; 
    [self.tableView reloadData]; 
} 
-(void)updateData 
{ 
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Device"]; 
    request.returnsDistinctResults = YES; 
    //request.resultType = NSDictionaryResultType; 
    request.propertiesToFetch = @[@"serialNumber"]; 

    NSArray *fetchedObjects = [self.managedObjectContext 
           executeFetchRequest:request error:nil]; 

    NSArray *result = [fetchedObjects valueForKeyPath:@"serialNumber"]; 

    //there I get all serialNumbers of my devices and than I call method getStatus and get "new" status and than update it in Core Data. 
} 

是好辦法來解決這個問題呢?如果我只調用一次getStatus方法並獲取狀態數組,我認爲會更好。

也許我可以將所有serialNubers設置爲一個變量('xxx','yyyy','zzz'),然後在服務器上執行SELECT * FROM設備WHERE serialNumber(serialNuber)。

您認爲這可行嗎?我沒有經驗如何將數據從數組轉換爲字符串,例如('array_part1','array_part2'....)

+0

請正確標記您的問題;例如,瞭解平臺(OSX或iOS)比了解用於開發程序的IDE更重要。 – trojanfoe

+0

好的,對不起沒有問題。我會做的。 – Miras

回答

2

在代碼中的哪個位置,請撥打[UITableView reloadData]

一旦您從服務器檢索到新數據,您應該在您的tableview上調用reloadData。當你的服務器調用是異步服務器調用,而主線程繼續在一個單獨的線程運行,因此,我相信你有以下問題......

- (void) ... 
{ 
    [self getStatus:@"SERIAL_NUMBER"]; 
    [self reloadData]; // This will be called before the async server call above has finished 
} 

因此你重裝的原始數據,因此新數據可能在幾秒鐘後加載,不會顯示。

若要解決此問題,請調整[getStatus:]方法以調用[UITableView reloadData]方法服務器響應。

[request setCompletionBlock:^ 
{ 
    if([self isViewLoaded]) 
    { 
     [MBProgressHUD hideHUDForView:self.view animated:YES]; 
     if([request_b responseStatusCode] != 200) 
     { 
      ShowErrorAlert(@"Comunication error", @"There was an error communicating with the server"); 

     } 
     else 
     {     

      NSString *responseString = [request_b responseString]; 
      SBJsonParser *parser = [[SBJsonParser alloc] init]; 
      NSDictionary *result = [parser objectWithString:responseString error:nil]; 

      status = [result objectForKey:@"status"]; 
      NSInteger statusInt = [status intValue]; //change to int value 

      // Store the server response in NSManagedObject *device, 
      // which will be used as the data source in the tableView:cellForRowAtIndexPath: method 

      // Once stored, check the tableview isn't NULL and therefore can be accessed 
      // As this call is async the tableview may have been removed and therefore 
      // a call to it will crash 
      if(tableView != NULL) 
      { 
        [tableView reloadData]; 
      }   
     } 
    } 
}]; 

ASIHTTPRequest也不再由開發商的支持,我建議你看看AFNetworking


更新

響應於你現在與NSManagedObject

NSManagedObject *device = [self.devices objectAtIndex:indexPath.row]; 
[device setValue:statusInt forKey:@"status"]; //there is problem in save statusInt 

這是作爲statusInt引起在裝置內設置statusInt遇到的問題是NSInteger,其是伯數據類型而不是NSObject,如[NSManagedObject setValue:forKey:]所預期的那樣。從[NSManagedObject setValue:forKey:]的文檔中,方法的預期參數如下。

- (void)setValue:(id)value forKey:(NSString *)key 

因此你需要傳遞,在這種情況下,NSNumberNSInteger的問題在於,它僅僅是基於當前系統的最大int數據類型的dynamic typedef。從NSInteger的實現中,您可以看到抽象。

#if __LP64__ 
typedef long NSInteger; 
#else 
typedef int NSInteger; 
#endif 

如果你當前的系統是64位,它會使用更大的long數據類型。

現在,技術上來說,服務器返回的status值可以按原樣存儲,而不需要作爲NSString進行任何轉換。當您需要檢索並使用int的主數據類型時,可以使用已使用的[NSString intValue]方法。

儘管最好使用NSNumberFormatter,它可以用於基於locale的數字調整並確保不存在無效字符。

NSString *status = [result objectForKey:@"status"]; 
NSNumberFormatter * f = [[NSNumberFormatter alloc] init]; 
NSNumber * statusNumber = [f numberFromString:status]; 
NSManagedObject *device = [self.devices objectAtIndex:indexPath.row]; 
[device setValue:statusNumber forKey:@"status"]; 

要當你想使用的int你的代碼中,只需調用[NSNumber intValue]檢索主數據類型。

NSNumber *statusNumber = [device objectForKey:@"status"]; 
int statusInt = [statusNumber intValue]; 

至於你用無限循環有問題,這是由所謂的[... getStatus:atIndexPath:],其中包含了方法調用reloadData,從[UITableView tableView:cellForRowAtIndexPath:]內造成的。

這是因爲reloadData實際上稱爲[UITableView tableView:cellForRowAtIndexPath:]。 因此你的代碼繼續去爲以下...

Initial UITableView data load -> tableView:cellForRowAtIndexPath: -> getStatus:atIndexPath: -> Server Response -> reloadData -> tableView:cellForRowAtIndexPath: -> getStatus:atIndexPath: -> Server Response -> reloadData -> ... 

不幸的是,你不能只是空軍一號細胞更新,您有權要求UITableView使用reloadData重新加載所有數據。因此,如果可能,您需要調整服務器以返回設備的唯一ID,以便您只能調整NSManagedObject內的更新設備。

對於getStatus方法的建議更改可以僅使用serialNumber,如果它作爲密鑰存儲在NSManagedObject內。

- (void) getStatus:(NSString*)serialNumber 
+0

我編輯我的問題與另一個問題。感謝那個AFNetworking,我會研究它。謝謝 – Miras

+0

在你的代碼中,你使用CoreData來設置設備?我看到你有一個名爲'devices'的'NSArray',它包含'NSManagedObject'。 '[self.devices objectAtIndex:indexPath.row]'在[self getStatus:]'方法的服務器響應中不起作用的原因是'indexPath.row'來自'[UITableViewDelegate tableView:cellForRowAtIndexPath:] '因此'indexPath.row'在服務器響應代碼中是'NULL'。請閱讀[CoreData](http://developer.apple.com/library/mac/#documentation/cocoa/Conceptual/CoreData/cdProgrammingGuide.html)和[NSManagedObject](http://bit.ly/17oYVs8) –

+0

我更新我的問題,現在我知道如何保存,但有新問題。 – Miras