JSMessageViewController = Passing PFObject into (id<JSMessageData>) - ios

I am using parse as my database to store the text a user enters, and then display it onto the JSMessageViewController.
I am having difficulty understanding why my PFObject will not pass, and instead, I see empty message cells..
In my code here as you can see, if i pass either of the // code, it crashes, i know nil wont work and thats why i am getting the blank... but how do I pass a PFObject into the JSMessageData ?
- (id<JSMessageData>)messageForRowAtIndexPath:(NSIndexPath *)indexPath
{
//PFObject *chat = self.chats[(NSUInteger) indexPath.row];
//return chat;
//PFObject *chat = self.chats[indexPath.row];
//NSString *message = chat[kMMKChatTextKey];
//return message;
return nil;
}
JSMessageData has 3 instances : - (NSDate *)date, - (NSString *)sender, and - (NSString *)text ....
http://cocoadocs.org/docsets/JSMessagesViewController/4.0.0/Protocols/JSMessageData.html
Has anyone worked with this ? or can you help me figure out how I can pass the PFOject through - Parse is working fine, and the text entered, and after that when i press send, its stored in Parse.
-(void)didSendText:(NSString *)text fromSender:(NSString *)sender onDate:(NSDate *)date
{
if (text.length != 0){
PFObject *chat = [PFObject objectWithClassName:#"Chat"];
[chat setObject:self.chatRoom forKey:kMMKChatChatroomKey];
[chat setObject:self.currentUser forKey:kMMKChatFromUserKey];
[chat setObject:self.withUser forKey:kMMKChatToUserKey];
[chat setObject:text forKey:kMMKChatTextKey];
[chat saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
[self.chats addObject:chat];
//[JSMessageSoundEffect playMessageSentSound];
[self.tableView reloadData];
[self finishSend];
[self scrollToBottomAnimated:YES];
}];
}
}

use objectForKey method on PFObject, and pass appropriate key to retrieve text

The code below should do what you need.
- (id<JSMessageData>)messageForRowAtIndexPath:(NSIndexPath *)indexPath
{
PFObject *chat = self.chats[indexPath.row];
NSString *message = chat[kMMKChatTextKey];
JSMessage *jsMessage = [[JSMessage alloc] initWithText:message sender:nil date:nil];
return jsMessage;
}

Related

How do you properly implement async search results?

I made a clone of UITableView called TableView with its own dataSource and delegate that mimics the original UITableView but is intended to do some things differently. I also made a GoogleSuggest class with its own delegate that requests google autocomplete suggestions from a known URL.
The GoogleSuggest class has this method:
- (void)requestSuggestionsForText:(NSString *)text {
[NSThread detachNewThreadSelector:#selector(asyncRequestSuggestionsForText:)
toTarget:self
withObject:text];
}
When called it dispatches this private background thread:
- (void)asyncRequestSuggestionsForText:(NSString *)text;
When it receives results it calls this delegate method:
- (void)googleSuggestDidReceiveResult:(GoogleSuggestResult *)result;
Everything worked fine with little controlled experiments until I put it all together in the main ViewController.
Initially, this method returned a "UI API called on a background thread" error:
#pragma mark - GoogleSuggestDelegate
- (void)googleSuggestDidReceiveResult:(GoogleSuggestResult *)result {
_googleSuggestions = result.suggestions;
[_tableView reloadData];
}
Then I replaced the last line with this and it worked:
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
Now, I'm getting a "-[__NSCFNumber length]: unrecognized selector sent to instance 0xbbe7252cd9143595" error.
The result.suggestions is a simple NSMutableArray with NSString variables, no NSNumbers anywhere.
This works and I get to see all results logged:
- (TableViewCell *)tableView:(tableView *)tableView cellAtIndex:(NSUInteger)index {
TableViewCell *cellView = [[TableViewCell alloc] init];
NSString *result = [_googleSuggestions objectAtIndex:index];
NSLog(#"Result: %#", result);
// cellView.titleLabel.text = result;
return cellView;
}
This also works and I get to see all results logged:
- (TableViewCell *)tableView:(tableView *)tableView cellAtIndex:(NSUInteger)index {
TableViewCell *cellView = [[TableViewCell alloc] init];
NSString *result = [_googleSuggestions objectAtIndex:index];
NSLog(#"Result: %#", result);
cellView.titleLabel.text = #"example text";
return cellView;
}
This fails when I try to assign the result to the titleLabel.text:
- (TableViewCell *)tableView:(tableView *)tableView cellAtIndex:(NSUInteger)index {
TableViewCell *cellView = [[TableViewCell alloc] init];
NSString *result = [_googleSuggestions objectAtIndex:index];
NSLog(#"Result: %#", result);
cellView.titleLabel.text = result;
return cellView;
}
It makes no sense, it's clearly an NSString variable assigned to an object that has no problem with NSString variables like shown in the working examples above.
How do you properly implement async search results?
How do you properly update UI elements from a background thread?

How to use CNContactPickerViewController with objective c?

Hi I'm new to iOS development. I want to pick a contact from default contacts app. For that i created an application that lets user to pick a contact from the iPhone default contacts app. For iOS 9+ version, I'm using the following snipped.
- (IBAction)btnAction:(id)sender {
CNContactPickerViewController *contactPicker = [[CNContactPickerViewController alloc] init];
contactPicker.delegate = self;
contactPicker.displayedPropertyKeys = (NSArray *)CNContactGivenNameKey;
[self presentViewController:picker animated:YES completion:nil];
}
-(void) contactPicker:(CNContactPickerViewController *)picker didSelectContact:(CNContact *)contact{
NSLog(#"Contact : %#",contact);
}
-(void)contactPickerDidCancel:(CNContactPickerViewController *)picker {
NSLog(#"Cancelled");
}
I also added CNContactPickerDelegate delegate in my uiviewcontroller. When i execute the above code, it opens the contacts app, But when Tap a contact the app becomes blank.
Thanks in advance and can anyone please share your knowledge to use CNContactPickerViewController in Objective-C.
The issue is caused by this code:
contactPicker.displayedPropertyKeys = (NSArray *)CNContactGivenNameKey;
The displayedPropertyKeys expects an NSArray which contains NSString values. In your code, you are trying to type cast an NSString to NSArray and set as the value of this property.
You need to change your code to:
contactPicker.displayedPropertyKeys = #[CNContactGivenNameKey];
#pragma mark - CNContactPickerViewController Delegate method implementation
(void)contactPicker:(CNContactPickerViewController *)picker didSelectContact:(CNContact *)contact
{
NSMutableArray *contactNumberArray = [[NSMutableArray alloc]init];
selectedName=[NSString stringWithFormat:#"%#",contact.givenName];
NSLog(#"%#",selectedName);
NSString *tempString = [NSString stringWithFormat:#"name : %# %# %#\n",contact.givenName, contact.familyName, contact.organizationName];
// // 1. (Phone Numbers)
tempString = [NSString stringWithFormat:#"%#phoneNumbers : ",tempString];
// NSArray*phoneNumber = contact.phoneNumbers;
for (CNLabeledValue *phoneNumber in contact.phoneNumbers)
{
CNPhoneNumber *phone = phoneNumber.value;
tempString = [NSString stringWithFormat:#"%#<%#>",tempString,phone.stringValue];
[contactNumberArray addObject:phone];
selectedPhNumber=[[NSString stringWithFormat:#"%#",phone.stringValue] stringByReplacingOccurrencesOfString:#" " withString:#""];
NSLog(#"%#",selectedPhNumber);
}
//2. (Emails)
tempString = [NSString stringWithFormat:#"%#\n Email : ",tempString];
for (CNLabeledValue *email in contact.emailAddresses)
{
selectedEmail=[NSString stringWithFormat:#"%#", email.value];
tempString = [NSString stringWithFormat:#"%#<%#>",tempString,email.value];
[contactNumberArray addObject:email];
NSLog(#"%#",selectedEmail);
}
[self sendRefferelDetailsToServer];
}
-(void)contactPicker:(CNContactPickerViewController *)picker didSelectContacts:(NSArray<CNContact *> *)contacts{
NSLog(#" %#",contacts);
CNContact *contact=[contacts objectAtIndex:0];
NSLog(#"name = %#",contact.givenName);
}
[1]: https://i.stack.imgur.com/9Sp1G.png use above code to for fetch given name from multiple selections,
comment the following line and try again.
//contactPicker.displayedPropertyKeys = (NSArray *)CNContactGivenNameKey;

Data retrieved but Table Cell UILabel is empty?

I'm retrieving entity data from an endpoint with the following code (I've built my app on Drupal's iOS SDK), and I'm trying to display it in my TableView cell.
That said, when I use the following code to display it in my cell, it doesn't seem to want to work (the label just appears empty)? See console data below as well.
TableViewController.h
#property (strong, nonatomic) NSMutableArray *messages;
TableViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
NSDictionary *entityData = [NSDictionary dictionaryWithObject:[NSString stringWithFormat:#"1"] forKey:#"uid"];
[DIOSEntity
entityGet:entityData
name:#"entity_message"
eid:#"uid"
success:^(AFHTTPRequestOperation *op, id response) {
self.messages = (NSMutableArray *)response;
NSLog(#"This is all of the data from response %#", response); }
failure:^(AFHTTPRequestOperation *op, NSError *err) { NSLog(#"failed to get data"); }
];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *PointsTableIdentifier = #"MyMessagesCell";
MyMessagesCell *cell = (MyMessagesCell *)[tableView dequeueReusableCellWithIdentifier:PointsTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"MyMessagesCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
NSDictionary *receivedMessages = [self.messages objectAtIndex:indexPath.row];
[[cell subjectLine] setText:[receivedMessages objectForKey:#"field_message_body"]];
NSLog(#"Received message subject are here %#", receivedMessages);
return cell;
}
CONSOLE DATA returns as:
2015-11-23 18:26:47.998 [624:153845] This is all of the data from response {
arguments = (
);
data = (
);
"field_message_body" = {
und = (
{
format = "<null>";
"safe_value" = "Testing message center";
value = "Testing message center";
}
);
};
"field_message_group_ref" = (
);
"field_message_subject" = {
und = (
{
format = "<null>";
"safe_value" = Testing;
value = Testing;
}
);
};
The tableView finished loading before you got the response. You can log something in
numberOfRowsInSection: and cellForRowAtIndexPath method see if it was before "This is all of the data from response ...".
You can call [self.tableview reloadData] on main thread to reload the tableview after you get the messages.
You need to make a better management of the response data. As #limfinity said, the responseData is a NSDictinary, not a NSMutableArray.
Also, you should reload the tableview after setting the messages in self.messages, so the table gets the new data from the 'new' self.messages:
[DIOSEntity
entityGet:entityData
name:#"entity_message"
eid:#"uid"
success:^(AFHTTPRequestOperation *op, id response) {
self.messages = (NSMutableArray *)response;
NSLog(#"This is all of the data from response %#", response); }
dispatch_async(dispatch_get_main_queue(), ^(void){
[self.tableView reloadData];
});
failure:^(AFHTTPRequestOperation *op, NSError *err) { NSLog(#"failed to get data"); }
];
EDIT
Just to make a simple (but not so correct) change to make this work and don't crash, you should say:
self.messages = [NSMutableArray arrayWithObject:(NSDictionary*)response];
instead of:
self.messages = (NSMutableArray *)response;
But I think you should go deeper and make the response be a NSArray, not just one NSDictionary (multiple NSDictionaries, instead of just one)
Based on your console logs:
2015-11-23 18:26:47.998 [624:153845] This is all of the data from response {
arguments = (
);
data = (
);
"field_message_body" = {//This is not a String!
und = (
{
format = "<null>";
"safe_value" = "Testing message center";
value = "Testing message center";
}
);
};
[receivedMessages objectForKey:#"field_message_body"] is not a string but a dictionary.
You need to parse that object a little more:
NSString *value = receivedMessages[#"field_message_body"][#"und"][#"value"];
[[cell subjectLine] setText:value];
And also don't forget to reload the tableview after you fetch the data.

message from debugger:terminated due to memory pressure IOS?

in server side data i am getting 17000 users names.when i get 1000 user names ofter Xcode is crashing giving these error message from debugger:terminated due to memory pressure please help me how to get 17000 user names data how to handle without memory presser.i got these problem in real device.
why i am taking array in app delegate i need to use these 17000 user names in so many view controllers
I am declare array
AppDelegate.h
#property (nonatomic,retain) NSMutableArray *userNamesGettingArrayObj;
I am declare string
ModelClass.h
#property (nonatomic,strong) NSString *nameString;
ModelClass.m
// i am getting server data in these dictionary object
NSDictionary *dictobj=[NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&err];
for (int i = 0; i<=[[dictobj valueForKey:#"name"] count]-1;i++)
{
_nameString=[[dictobj valueForKey:#"name"]objectAtIndex:i];
[delegate.userNamesGettingArrayObj addObject:_nameString];
}
viewController.m
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [delegate.userNamesGettingArrayObj count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (_tableViewObj == tableView) {
static NSString *ide=#"ide";
UITableViewCell *cell=[_tableViewObj dequeueReusableCellWithIdentifier:ide];
if (cell==nil) {
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ide];
}
cell.textLabel.text=[delegate.userNamesGettingArrayObj objectAtIndex:indexPath.row];
return cell;
}
}
I suspect that your repeated repeated repeated use of valueForKey may be the problem. Whether it is the problem or not, it is so inefficient it hurts my eyes. About 100 times faster:
NSArray* names = dictObj [#"name"];
NSMutableArray* userNames = delegate.userNamesGettingArrayObj;
for (NSString* nameString in names)
[names addObject:nameString];
17,000 names should be no problem whatsoever unless there's something wrong with your code.
valueForKey is a high-level method that is usually entirely inappropriate for processing JSON, or for accessing anything stored in a dictionary. Unless you have a very good reason (one that you could explain if asked about it), use objectForKey or just [#"someKey"].
Have to tried??
make response dict golable and
cell.textlable.text=[dictobj valueForKey:#"name"]objectAtIndex:indexpath.row];
Dont get that much data from sever at same time, use load more button or auto hit functions when your table reach at end of list.
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;{
if(nearByPlacesTableView.contentOffset.y >= (nearByPlacesTableView.contentSize.height - nearByPlacesTableView.bounds.size.height)) {
if (isPageRefresing) {
// [self performSelector:#selector(getRecords:) withObject:nextPageTokenString afterDelay:0.0f];
[self performSelectorInBackground:#selector(getRecords:) withObject:nextPageTokenString];
}
}
}
// HTTP Utility class
-(void)getRecords:(NSString *)token{
NSString *serverUrl;
if ([self.headStr isEqualToString:#"Nearby"])
{
serverUrl = [NSString stringWithFormat:#"https://maps.googleapis.com/maps/api/place/nearbysearch/json?pagetoken=%#&key=AIzaSyCd2",token];
}else{
serverUrl = [NSString stringWithFormat:#"https://maps.googleapis.com/maps/api/place/textsearch/json?pagetoken=%#&key=AIzaSyCd2",token];
}
//Create URL and Request
NSURL * url = [NSURL URLWithString:serverUrl];
NSURLRequest * request = [NSURLRequest requestWithURL:url];
NSURLResponse * response;
NSError * error = nil;
//Send Request
NSData * data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if (error == nil)
{
NSDictionary * json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSMutableArray *nextpageArr = [NSMutableArray new];
nextpageArr = [[json valueForKey:#"results"] mutableCopy];
nextPageTokenString=[json valueForKey:#"next_page_token"];
for (id dict in [json valueForKey:#"results"])
{
NSMutableDictionary *mutableDict;
if ([dict isKindOfClass:[NSDictionary class]]) {
mutableDict=[dict mutableCopy];
}
else{
mutableDict=dict;
}
[mutableDict setValue:#"0" forKey:#"checked"];
[mutableDict setValue:#"0" forKey:#"is_favourite"];
[nextpageArr addObject:mutableDict];
}
NSString *status=[json valueForKey:#"status"];
if ([status isEqualToString:#"INVALID_REQUEST"]) {
isPageRefresing=NO;
}else if ([status isEqualToString:#"OK"]){
isPageRefresing=YES;
}
if (nextpageArr.count) {
[self.nearbyVenues addObjectsFromArray:nextpageArr];
}
[nearByPlacesTableView reloadData];
[SVProgressHUD dismiss];
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"No Internet" message:#"Please check your internet connection." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
}
//i store all data into at time when i am using these code
delegate.userNamesGettingArrayObj=[[[NSArray arrayWithObject:dictobj]valueForKey:#"name"]objectAtIndex:0];

Update data in iOS TableView cells from webserver (ASIHTTPRequest, PHP, mysql)

I have tableview where is name and status. Status is changed when come apple push notification (APNS).
But I have this problem. What can I do, if notification didn't come? Or if user tap on close button of this message.
I try to update table by using ASIHTTPRequest:
- (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;
}
I try this to change status before cell is loading...
- (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];
}
Or it is better way to change status in my table view if apple notification didn't come or user didn't tap on notification message? Thanks
EDIT:
I don't know how to store data to NSManagedObject *device. Can you help me with this?
I try this, but it didn't works: (on place where you write)
NSInteger statusInt = [status intValue]; //change to int value
NSManagedObject *device = [self.devices objectAtIndex:indexPath.row];
[device setValue:statusInt forKey:#"status"];
EDIT2:
I get it, but problem is with reload table data
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
// [device setValue:#5 forKey:#"status"]; //if I do this it is ok status is integer16 type
and second problem is in that reload table data. I put there this
[self.tableView reloadData]
but It reloading again and again in loop, what is wrong? I thing there is infinite loop, if I didn't reload table data changes will be visible in next app load. I think problem is that I call
- (void) getStatus:(NSString *)serialNumber atIndexPath:(NSIndexPath *)indexPath
{}
in
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
}
Better should be in viewDidLoad or viewDidApper, but I don't know how make loop for all devices and call
[self getStatus:[device valueForKey:#"serialNumber"] atIndexPath:indexPath];
on that place.
EDIT3:
what if I do it like this:
- (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.
}
Is that good way to solve this problem? I think better will be if I call getStatus method only one times and get array of statuses.
Maybe I can set all serialNubers in one variable ('xxx','yyyy','zzz') and on server do SELECT * FROM Devices WHERE serialNumber in (serialNuber).
Do you think this could work? I don't have experience how to take data from array to string like ('array_part1','array_part2'....)
Where in your code do you call [UITableView reloadData]?
You should call reloadData on your tableview once you have retrieved the new data from the server. As your server call is async the server call will run on a separate thread while the main thread continues, therefore I presume you have the following problem...
- (void) ...
{
[self getStatus:#"SERIAL_NUMBER"];
[self reloadData]; // This will be called before the async server call above has finished
}
Therefore you are reloading the original data and therefore the new data, which may have loaded a few seconds after, wont be shown.
To fix this, adjust the [getStatus:] method to call the [UITableView reloadData] method on server response.
[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 is also no longer supported by the developers, I suggest you look into AFNetworking.
Update
In response to the problem you are now having with setting the statusInt within the device NSManagedObject
NSManagedObject *device = [self.devices objectAtIndex:indexPath.row];
[device setValue:statusInt forKey:#"status"]; //there is problem in save statusInt
This is caused as statusInt is an NSInteger which is a primary datatype and not an NSObject as expected by [NSManagedObject setValue:forKey:]. From the documentation for [NSManagedObject setValue:forKey:], the methods expected parameters are as follows.
- (void)setValue:(id)value forKey:(NSString *)key
Therefore you need to pass, in this case, an NSNumber. The problem with NSInteger is that it's simply a dynamic typedef for the largest int datatype based on the current system. From NSInteger's implementation you can see the abstraction.
#if __LP64__
typedef long NSInteger;
#else
typedef int NSInteger;
#endif
If your current system is 64-bit it will use the larger long datatype.
Now, technically the returned status value from the server can be stored as it is without any conversion as an NSString. When you need to retrieve and use the primary datatype of int you can use the [NSString intValue] method you have already used.
Although it's best practice to use a NSNumberFormatter which can be useful for locale based number adjustments and ensuring no invalid characters are present.
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"];
To retrieve the primary datatype when you wish to use the int within your code, simply call the [NSNumber intValue].
NSNumber *statusNumber = [device objectForKey:#"status"];
int statusInt = [statusNumber intValue];
As for the problem you are having with the infinite loop, this is caused by called [... getStatus:atIndexPath:], which contains the method call reloadData, from within [UITableView tableView:cellForRowAtIndexPath:].
This is because reloadData actually calls [UITableView tableView:cellForRowAtIndexPath:].
Therefore your code continuously goes as the following...
Initial UITableView data load -> tableView:cellForRowAtIndexPath: -> getStatus:atIndexPath: -> Server Response -> reloadData -> tableView:cellForRowAtIndexPath: -> getStatus:atIndexPath: -> Server Response -> reloadData -> ...
Unfortunately you cant just force one cell to update, you have to request the UITableView to reload all data using reloadData. Therefore, if possible, you need to adjust your server to return an unique ID for devices so you can adjust only the updated device within your NSManagedObject.
A suggested alteration for the getStatus method could be just to use the serialNumber if this is stored within the NSManagedObject as a key.
- (void) getStatus:(NSString*)serialNumber

Resources