I have been trying this for quite sometime now, but I just couldn't be able to post successfully to my server. I have read this, github object mapping overview for the Restkit and, the Gist restKit tutorial.
My Problem
I am trying to post sign in information(nickname,hardwareId,phone model) and get the AccountId from my server. But I am getting this response from the console:
GuessTheImage[6832:70b] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<AccountsClass 0x8c5cba0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key AccountInfo.'
What I think is the problem
I believe I am messing up the way I store the data right before the mapping part. But I am not sure where exactly.
The JSON that I am trying post should look like this
{
"DeviceType": "sample string 1",
"HardwareId": "sample string 2",
"NickName": "sample string 3",
"AccountId": 4
}
Overview of the program
I created the variables for mapping in the AccountClass. From loginviewcontroller, I get the device type, hardwareId and nickname after the user clicks login button and assign those variables to the variables in AccountClass and map it POST if afterwards.
AccountClass.h
#import <Foundation/Foundation.h>
#interface AccountsClass : NSObject
#property (nonatomic, strong,retain)NSString *DeviceType;
#property (nonatomic,strong)NSNumber *AccountId;
#property (nonatomic,strong) NSString *NickName;
#property (nonatomic,strong) NSNumber *HardwareId;
#end
LoginViewController.h
#import <UIKit/UIKit.h>
#interface LoginViewController : UIViewController<UITextFieldDelegate>
#property (strong, nonatomic) IBOutlet UITextField *usernameTextField;
#property (strong, nonatomic) IBOutlet UIButton *submitButton;
#property (nonatomic,readonly) NSUUID *identifierForVendor;
#property(nonatomic, readonly, retain) NSString *model;
#property (nonatomic,readonly,retain)NSString *StoreIdentifierForVendor;
#property (nonatomic,readonly,retain)NSString *StoreTheModel;
- (IBAction)submit:(id)sender;
#property (nonatomic,strong)NSString *nickname;
#end
LoginViewController.m
#import "LoginViewController.h"
#import <RestKit/RestKit.h>
#import "AccountsClass.h"
#interface LoginViewController ()
#end
#implementation LoginViewController
#synthesize usernameTextField;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(dissmissKeyboard)];
[self.view addGestureRecognizer:tap];
[usernameTextField setDelegate:self];
}
-(void)loadPostRequest
{
_StoreIdentifierForVendor = [[[UIDevice currentDevice]identifierForVendor]UUIDString];
_StoreTheModel = [UIDevice currentDevice].model;
_nickname = usernameTextField.text;
AccountsClass *AccountInfo = [[AccountsClass alloc] init];
AccountInfo.NickName = _nickname;
NSNumberFormatter *hardwareIdentification = [[NSNumberFormatter alloc]init];
[hardwareIdentification setNumberStyle:NSNumberFormatterScientificStyle];
NSNumber *hwreID =[hardwareIdentification numberFromString:_StoreIdentifierForVendor];
AccountInfo.HardwareId = hwreID;
AccountInfo.DeviceType =_StoreTheModel;
RKObjectMapping *responseMapping = [RKObjectMapping mappingForClass:[AccountsClass class]];
[responseMapping addAttributeMappingsFromArray:#[#"NickName", #"HardwareId", #"DeviceType",#"AccountId"]];
NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful); // Anything in 2xx
RKResponseDescriptor *AccountDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:responseMapping method:RKRequestMethodAny pathPattern:nil keyPath:nil statusCodes:statusCodes];
RKObjectMapping *requestMapping = [RKObjectMapping requestMapping]; // objectClass == NSMutableDictionary
[requestMapping addAttributeMappingsFromArray:#[#"AccountInfo.NickName", #"AccountInfo.HardwareId", #"AccountInfo.DeviceType",#"AccountInfo.AccountId"]];
// For any object of class Article, serialize into an NSMutableDictionary using the given mapping and nest
// under the 'article' key path
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:requestMapping objectClass:[AccountInfo class] rootKeyPath:nil method:RKRequestMethodAny];
RKObjectManager *manager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:#"https://picquiz.azurewebsites.net"]];
[manager addRequestDescriptor:requestDescriptor];
[manager addResponseDescriptor:AccountDescriptor];
// POST to create
[manager postObject:AccountInfo path:#"/Accounts" parameters:nil success:nil failure:nil];
}
-(void)dissmissKeyboard
{
[usernameTextField resignFirstResponder];
}
- (IBAction)submit:(id)sender {
[self loadPostRequest];
}
#end
I will appreciate your help.
Your problem appears to be:
[requestMapping addAttributeMappingsFromArray:#[#"AccountInfo.NickName", #"AccountInfo.HardwareId", #"AccountInfo.DeviceType",#"AccountInfo.AccountId"]];
because the data that you are trying to POST doesn't have nested data like that. It looks like it should be:
[requestMapping addAttributeMappingsFromArray:#[#"NickName", #"HardwareId", #"DeviceType",#"AccountId"]];
Related
I'm using the AFNetworking library to parse json using the AFHTTPClient. I can verify that the json is being parsed within the client block and send that data to my json model. However, when I try to access the json model from outside the block I get no data. How can I pass the parsed json data to the json model then access that model data elsewhere in the app?
the AFHTTPClient subclass / singleton:
#import <Foundation/Foundation.h>
#import "AFHTTPClient.h"
#interface JsonClient : AFHTTPClient
+ (JsonClient *)sharedClient;
#end
#import "JsonClient.h"
#import "AFJSONRequestOperation.h"
static NSString *const kJsonBaseURLString = #"https://alpha-api.app.net/";
#implementation JsonClient
+ (JsonClient *)sharedClient {
static JsonClient *_sharedClient = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedClient = [[JsonClient alloc] initWithBaseURL:[NSURL URLWithString:kJsonBaseURLString]];
});
return _sharedClient;
}
- (id)initWithBaseURL:(NSURL *)url {
self = [super initWithBaseURL:url];
if (!self) {
return nil;
}
[self registerHTTPOperationClass:[AFJSONRequestOperation class]];
[self setDefaultHeader:#"Accept" value:#"application/json"];
return self;
}
#end
the JSON model data:
#import <Foundation/Foundation.h>
#interface TheJson : NSObject
#property (nonatomic, copy) NSString *createdAt;
#property (nonatomic, copy) NSString *userText;
- (id)initWithDictionary:(NSDictionary *)dict;
#end
#import "TheJson.h"
#implementation TheJson
- (id)initWithDictionary:(NSDictionary *)dict {
self = [super init];
if (self) {
self.createdAt = [dict objectForKey:#"created_at"];
self.userText = [dict objectForKey:#"text"];
}
return self;
}
#end
the ViewController to update the user interface:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#end
#import "ViewController.h"
#import "JsonClient.h"
#import "TheJson.h"
#interface ViewController ()
#property (weak) IBOutlet UILabel *createdLabel;
#property (weak) IBOutlet UILabel *textLabel;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (IBAction)fetchJsonData:(id)sender {
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
[[JsonClient sharedClient] getPath:#"stream/0/posts/stream/global" parameters:nil
success:^(AFHTTPRequestOperation *operation, id JSON) {
NSArray *postsFromResponse = [JSON valueForKeyPath:#"data"];
NSDictionary *dictFromArray = postsFromResponse[0];
TheJson *jsonObject = [[TheJson alloc] initWithDictionary:dictFromArray];
NSLog(#"createdAt is %#", jsonObject.createdAt);
NSLog(#"text from user is %#", jsonObject.userText);
[self updateInterface];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error is %#", [error description]);
}
];
}
- (void)updateInterface {
TheJson *thejson;
[_createdLabel setText:thejson.createdAt];
[_textLabel setText:thejson.userText];
}
#end
You haven't passed the new jsonObject out of the block nor stored it anywhere. A short term answer is to declare updateInterface to take the jsonObject as a parameter.
So your updateInterface becomes updateInterface: something like this:
- (void)updateInterface:(TheJson*)thejson {
[_createdLabel setText:thejson.createdAt];
[_textLabel setText:thejson.userText];
}
...and then within your block, you call this method like this:
[self updateInterface:jsonObject];
Longer term, if your app has many of these objects and/or needs to hold onto them for any amount of time, you probably want to think about how you will store and organize these as you download them.
I have a single view application where the ViewController contains a UIView of custom class CPTGraphHostingView so that it holds a CorePlot graph. The content of that UIView is managed by an NSObject sub-class called SimpleScatterPlot. This SimpleScatterPlot object holds all the parameters needed to configure the graph (axis ranges, labels, number of points, etc.)
ViewController.h
#import <UIKit/UIKit.h>
#import "CorePlot-CocoaTouch.h"
#import "SimpleScatterPlot.h"
#interface ViewController : UIViewController
{
IBOutlet CPTGraphHostingView *_graphHostingView;
SimpleScatterPlot *_scatterPlot;
NSMutableData *dataConexion;
}
#property (nonatomic,strong) NSArray *valor;
#property (nonatomic,strong) NSArray *strAnoMes;
#property (nonatomic,strong) NSArray *indicador;
#property (nonatomic, retain) SimpleScatterPlot *scatterPlot;
#end
In ViewController.m I have some methods to initialise a few arrays from some JSON data:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize indicador,valor,strAnoMes;
- (void)viewDidLoad
{
[super viewDidLoad];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSString *urlString = #"http://xxxx/ios/datosgrafica.php";
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
(void)[[NSURLConnection alloc] initWithRequest:request delegate:self];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
dataConexion = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)theData
{
[dataConexion appendData:theData];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
indicador = [NSJSONSerialization JSONObjectWithData:dataConexion options:nil error:nil];
// ARRAYS OF INTEREST
strAnoMes = [indicador valueForKey:#"StrAnoMes"];
valor = [indicador valueForKey:#"Valor"];
self.scatterPlot = [[SimpleScatterPlot alloc] initWithHostingView:_graphHostingView andData:pointArray];
[self.scatterPlot initialisePlot];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
UIAlertView *errorView = [[UIAlertView alloc] initWithTitle:#"Error" message:#"The download could not complete - please make sure you're connected to either 3G or Wi-Fi." delegate:nil cancelButtonTitle:#"Dismiss" otherButtonTitles:nil];
[errorView show];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
In the SimpleScatterPlot.m I would like to use the array "valor" to configure axis ranges, and I would like to use the array "strAnoMes" to draw custom labels in the xAxis.
What do I have to do so that I can pass those arrays defined in ViewController to SimpleScatterPlot?
I have tried to #import "ViewController.h" but it gives me errors. Any other ideas? What is the best way to approach this situation?
You can take two properties in SimpleScatterPlot.
SimpleScatterPlot.h
#property (nonatomic, retain) NSArray * strAnoMes;
#property (nonatomic, retain) NSArray * valor;
SimpleScatterPlot.m
#synthesize strAnoMes;
#synthesize valor;
In ViewController.m, After creating scatterPlot in connectionDidFinishLoading:, assign the values to above properties as below.
self.scatterPlot.strAnoMes = strAnoMes;
self.scatterPlot.valor = valor;
One way to do this is to create a simple data object and pass it directly into your SimpleScatterPlot object:
Data Object:
#interface SimpleScatterPlotData : NSObject
#property (...) NSArray *valor;
#property (...) NSArray *strAnoMes;
#end
#implementaton SimpleScatterPlotData
#synthesize valar;
#synthesize strAnoMes;
-(void)dealloc
{
...
...
[super dealloc];
}
#end
Implement a load method in your SimpleScatterPlot class:
#interface SimpleScatterPlot
-(void)loadData:(SimpleScatterPlotData *)data;
#end
#implementation SimpleScatterPlot
-(void)loadData:(SimpleScatterPlotData *)data
{
NSArray *valor = data.valor;
NSArray *strAnoMes = data.strAnoMes;
/*
Do something
*/
}
#end
Then in your ViewController class:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
indicador = [NSJSONSerialization JSONObjectWithData:dataConexion options:nil error:nil];
// ARRAYS OF INTEREST
strAnoMes = [indicador valueForKey:#"StrAnoMes"];
valor = [indicador valueForKey:#"Valor"];
SimpleScatterPlotData *data = [[[SimpleScatterPlotData alloc] init] autorelease];
data.valor = valor;'
data.strAnoMes = strAnoMes;
self.scatterPlot = [[SimpleScatterPlot alloc] initWithHostingView:_graphHostingView andData:pointArray];
[self.scatterPlot loadData:data];
}
You could also change your current initializer or add a new initializer to your SimpleScatterPlot class so that you pass those arrays in when you alloc the object. So your the call to your initializer would look something like:
self.scatterPlot = [[SimpleScatterPlot alloc] initWithHostingView:_graphHostingView andData:pointArray andValor:valor andstrAnoMes:strAnoMes];
Then in your initializer you can set the object properties to those passed in values.
So I'm creating an array called fruits which I would like to share between multiple views. This is my code:
#import <foundation/Foundation.h>
#interface MyManager : NSObject {
NSMutableArray *fruits;
}
#property (nonatomic, retain) NSMutableArray *fruits;
+ (id)sharedManager;
#end
#import "MyManager.h"
static MyManager *sharedMyManager = nil;
#implementation MyManager
#synthesize fruits;
#pragma mark Singleton Methods
+ (id)sharedManager {
#synchronized(self) {
if (sharedMyManager == nil)
sharedMyManager = [[self alloc] init];
}
return sharedMyManager;
}
- (id)init {
if ((self = [super init])) {
fruits = [[NSMutableArray alloc] init];
}
return self;
}
-(void) dealloc{
self.fruits = nil;
[super dealloc];
}
#end
Now I'm using the following code so that I can use workouts in the new view
#import "MyManager.h"
#interface Chest : UIViewController {
IBOutlet MyManager *fruits;
}
#property (nonatomic, retain) IBOutlet MyManager *fruits;
-(IBAction) goToList: (id) sender;
#end
When a button is clicked, goToList is called, and I populate my array, fruits
#import "Chest.h"
#implementation Chest
#synthesize fruits;
-(IBAction) goToList:(id)sender{
MyManager *fruits = [MyManager sharedManager];
NSString *filePath;
NSString *fileContents;
filePath = [[NSBundle mainBundle] pathForResource:#"chest_strength" ofType:#"csv"];
fileContents = [[NSString alloc] initWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
fruits = [fileContents componentsSeparatedByString:#"\n"];
}
When I output the elements of *fruits in this view, everything works fine. Now when I try to access this same variable in the other view, it says the array is null. Here's the code for the second view:
#interface List : UIViewController {
IBOutlet MyManager *fruits;
}
#property (nonatomic, retain) IBOutlet MyManager *fruits;
#end
#import "List.h"
#import "MyManager.h"
#implementation List
#synthesize fruits
NSLog(#"%#", fruits); //This is the part that isn't displaying correctly. I'm getting a null here
So my question is, how do I do this so that I can get the array fruits that I populated in Chest and use it in List so that I can display the contents of the array in that view?
Thank you to everybody who answers. This problem is seriously bogging me down and I need to finish this project ASAP. Much appreciated.
You've changed a few things in this question but the fundamental problem remains: the array is a property of your singleton, and you are not treating it as such.
Whenever you refer to the array, outside of the singleton, do it like this:
[MyManager sharedManager].fruits
If you are accessing it frequently, you can create a local ivar, but you certainly wouldn't have it as an IBOutlet, which you are doing in your last code sample. How is that ever going to be set?
I have the following code to login to a web service and store the authentication token:
loginViewController.h
#interface loginViewController : UIViewController<XMLRPCConnectionDelegate>
#property (strong, nonatomic) IBOutlet UITextField *SSO;
#property (weak, nonatomic) IBOutlet UITextField *PASS;
#property (weak, nonatomic) IBOutlet UITextView *LoginError;
#property (nonatomic, retain) NSString *token;
#end
loginViewcontroller.m
#import "loginViewController.h"
#implementation loginViewController
#synthesize SSO;
#synthesize PASS;
#synthesize LoginError;
#synthesize token;
- (IBAction)coreLoginClicked:(id)sender {
NSURL *URL = [NSURL URLWithString: #"https://somesite"];
XMLRPCRequest *request = [[XMLRPCRequest alloc] initWithURL: URL];
XMLRPCConnectionManager *manager = [XMLRPCConnectionManager sharedManager];
[request setMethod:#"systemLogin" withParameters:[NSArray arrayWithObjects: SSO.text, PASS.text, nil]];
[manager spawnConnectionWithXMLRPCRequest: request delegate: self];
NSLog(#"Request body: %#", [request body]);
}
- (void)request: (XMLRPCRequest *)request didReceiveResponse: (XMLRPCResponse *)response {
if (![response faultCode]) {
token = [response object];
[self performSegueWithIdentifier:#"loginSegue" sender:self];
NSLog(#"Response object: %#", [response object]);
}
I have this code in my view controller that is displayed after successful login:
loginViewController* login = [[loginViewController alloc] init];
NSLog(#"Token: %#", login.token);
The value of login.token is nil. What am I doing wrong here? Is this the incorrect way of setting and accessing a global variable?
I was following the tutorial on Objective-C from lynda.com, and this way how they did it.. but maybe I missed something.
Thanks!
You're allocating a new instance, which means it'll be empty. If you want to be able to store objects in a class, you will have to use that instance to get the variables back.
Try accessing token via self:
NSLog(#"Token: %#", self.token);
Your second code bit does this: creates a new instance of the loginVC, and then checks to see if it has a token. You need to instantiate your loginVC, then do your login, and then it will have a value in token. Whatever class/method instantiates the loginVC will then be able to check that instance of loginVC for the token.
After making the rest call through RKObjectManager,it is not loading the objects when i don't have internet connection. I test with domain.local and my WIFI is Off.
I know that i can implement with "reachabilityObserver" but i don't know how can i make this.
My code :
#import "ViewInformationForm.h"
#import <RestKit/RestKit.h>
#interface User : NSObject {
NSNumber* _user_forfait;
NSNumber* _user_client_free;
NSNumber* _user_demande_portabilite;
NSNumber* _user_mail_confirm;
NSNumber* _user_mail_enregistrement_inscrption;
NSNumber* _user_mail_depart_expedition;
NSNumber* _user_mail_arrivee_expedition;
NSNumber* _user_activation;
NSNumber* _user_portabilite;
}
#property (nonatomic, retain) NSNumber* user_forfait;
#property (nonatomic, retain) NSNumber* user_client_free;
#property (nonatomic, retain) NSNumber* user_demande_portabilite;
#property (nonatomic, retain) NSNumber* user_mail_confirm;
#property (nonatomic, retain) NSNumber* user_mail_enregistrement_inscrption;
#property (nonatomic, retain) NSNumber* user_mail_depart_expedition;
#property (nonatomic, retain) NSNumber* user_mail_arrivee_expedition;
#property (nonatomic, retain) NSNumber* user_activation;
#property (nonatomic, retain) NSNumber* user_portabilite;
#end
#implementation User
#synthesize user_forfait = _user_forfait;
#synthesize user_client_free = _user_client_free;
#synthesize user_demande_portabilite = _user_demande_portabilite;
#synthesize user_mail_confirm = _user_mail_confirm;
#synthesize user_mail_enregistrement_inscrption = _user_mail_enregistrement_inscrption;
#synthesize user_mail_depart_expedition = _user_mail_depart_expedition;
#synthesize user_mail_arrivee_expedition = _user_mail_arrivee_expedition;
#synthesize user_activation = _user_activation;
#synthesize user_portabilite = _user_portabilite;
#end
#implementation ViewInformationForm;
#synthesize picker,pickerDate, forfaitNames;
#synthesize forfaitText, TextDateEnregistrement;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)LoadData {
RKObjectMapping* mapping = [RKObjectMapping mappingForClass:[User class]];
[mapping mapKeyPathsToAttributes:
#"data.user_forfait", #"user_forfait",
#"data.user_client_free", #"user_client_free",
#"data.user_demande_portabilite", #"user_demande_portabilite",
#"data.user_mail_confirm", #"user_mail_confirm",
#"data.user_mail_enregistrement_inscrption", #"user_mail_enregistrement_inscrption",
#"data.user_mail_depart_expedition", #"user_mail_depart_expedition",
#"data.user_mail_arrivee_expedition", #"user_mail_arrivee_expedition",
#"data.user_activation", #"user_activation",
#"data.user_portabilite", #"user_portabilite",
nil];
RKObjectManager *objectManager = [RKObjectManager sharedManager];
NSString* urlUID = [NSString stringWithFormat:#"/user/data?uid=%#",uuid];
RKObjectLoader *objectLoader = [objectManager objectLoaderWithResourcePath:urlUID delegate:self];
objectLoader.method = RKRequestMethodGET;
objectLoader.objectMapping = mapping;
[objectLoader send];
}
- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects {
User* user = [objects objectAtIndex:0];
NSString* info = [NSString stringWithFormat:
#"\n user_forfait : %# \n"
#"user_client_free : %#",[user user_forfait], [user user_client_free]];
NSLog(#"%#",info);
}
- (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError *)error {
RKLogError(#"Load of RKRequest %# failed with error: %#", objectLoader, error);
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView
{
}
*/
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[RKObjectManager objectManagerWithBaseURL:gRKCatalogBaseURL];
[self LoadData];
[super viewDidLoad];
self.forfaitNames = [[NSArray alloc] initWithObjects:
#"-- Sélectionnez un forfait --", #"Forfait 19,99 €", #"Forfait 15,90 €", #"Forfait 2 €",
#"Forfait 0 €", nil];
}
Error :
2012-01-24 09:59:32.120 Free M. Stats[13438:10703] I restkit:RKLog.m:30 RestKit initialized...
2012-01-24 09:59:32.127 Free M. Stats[13438:10703] I restkit.network.reachability:RKReachabilityObserver.m:369 Network availability has been determined for reachability observer <RKReachabilityObserver: 0x8987300 host=0.0.0.0 isReachabilityDetermined=YES isMonitoringLocalWiFi=652464 reachabilityFlags=-R tc----->
2012-01-24 09:59:32.129 Free M. Stats[13438:10703] E restkit.network:RKRequest.m:464 Failed to send request to http://freemobile-stats.local/user/data?uid=b070b4f0a581cf1a16312b7bbb31353c due to unreachable network. Reachability observer = <RKReachabilityObserver: 0x8987300 host=0.0.0.0 isReachabilityDetermined=YES isMonitoringLocalWiFi=652464 reachabilityFlags=-R tc----->
2012-01-24 09:59:32.130 Free M. Stats[13438:10703] E app:ViewInformationForm.m:102 Load of RKRequest <RKObjectLoader: 0x6e69050> failed with error: Error Domain=org.restkit.RestKit.ErrorDomain Code=2 "The client is unable to contact the resource at http://freemobile-stats.local/user/data?uid=b070b4f0a581cf1a16312b7bbb31353c" UserInfo=0x6c99270 {NSLocalizedDescription=The client is unable to contact the resource at http://freemobile-stats.local/user/data?uid=b070b4f0a581cf1a16312b7bbb31353c}
Thank you for your help.
AO.
This is how you register for the reachability notifications in RestKit:
// Register for changes in network availability
NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
[center addObserver:self selector:#selector(reachabilityDidChange:) name:RKReachabilityDidChangeNotification object:nil];
And here you catch the notification:
- (void)reachabilityDidChange:(NSNotification *)notification {
RKReachabilityObserver* observer = (RKReachabilityObserver *) [notification object];
RKReachabilityNetworkStatus status = [observer networkStatus];
if (RKReachabilityNotReachable == status) {
RKLogInfo(#"No network access!");
} else if (RKReachabilityReachableViaWiFi == status) {
RKLogInfo(#"Online via WiFi!");
} else if (RKReachabilityReachableViaWWAN == status) {
RKLogInfo(#"Online via Edge or 3G!");
}
}
You don't even have to register to Restkit reachability notifications system because it is already implemented in the RKRequest method.
So, if no internet connection is detected, your request will fail and this delegate (that you may have already implemented) is called :
- (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError *)error {
// No internet !
}
Beware, this delegate can also be called for others reasons, like when there is an error in the mapping of your data. But for simple cases it should be ok for what you want to do !
Obviously, it won't load data from the Internet if there's no Iternet connection. You may want to try one of the pre-implemented Reachability classes, for example: http://developer.apple.com/library/ios/#samplecode/Reachability/Listings/Classes_Reachability_h.html#//apple_ref/doc/uid/DTS40007324-Classes_Reachability_h-DontLinkElementID_5