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
Related
I'm trying to create a subclass of NSTask, that is augmented with a name and an activityDescription property, for the purpose of displaying status, in a UI in an OSX desktop application.
However, when I try to set the launchPath or arguments property on my subclass instance, I get these errors:
launchPath only defined for abstract class. Define -[Task launchPath]!
arguments only defined for abstract class. Define -[Task arguments]!
So, I defined setLaunchPath: and setArguments: as shown below, and I still get the same errors.
By the way, NSData stringValue is defined in NSData+Additions.h:
- (NSString *) stringValue {
return [[NSString alloc] initWithData:self encoding:NSUTF8StringEncoding];
}
Any help is greatly appreciated!
Task.h
#import <Foundation/Foundation.h>
#protocol TaskDelegate;
#interface Task : NSTask {
NSString *_launchTask;
NSArray *_arguments;
}
#property (weak, nonatomic) id<TaskDelegate> delegate;
#property (strong, nonatomic) NSString *name;
#property (strong, nonatomic) NSString *activityDescription;
//To be implemented by subclasses, should be called just before launch
- (void) setupTask;
- (BOOL) isConfigured;
//Launches the task - includes any setup required before the task is launched
- (void) launchAndWait;
- (void) setLaunchPath:(NSString *)launchPath;
- (void) setArguments:(NSArray *)arguments;
#end
#protocol TaskDelegate <NSObject>
- (void) task:(Task *)task didReceiveTaskError:(NSString *)errorString;
#end
Task.m
#import "Task.h"
#import "NSData+Additions.h"
#interface Task ()
#end
#implementation Task
- (id) init
{
self = [super init];
if (self) {
}
return self;
}
- (void) errorOccurred:(NSNotification *)notification {
if (_delegate) {
NSData *readData = [[notification userInfo] objectForKey:NSFileHandleNotificationDataItem];
NSString *outputString = [readData stringValue];
if (outputString.length)
[_delegate task:self didReceiveTaskError:outputString];
}
}
- (void) setupTask
{
//To be implemented by subclasses
}
- (BOOL) isConfigured
{
return (self.launchPath != nil);
}
//Process task conguration and execution is optional - if process task is not configured, this returns immediately
- (void) launchAndWait
{
//Allow setupTask to be used, without actually launching
if (![self isConfigured])
return;
NSPipe *errorPipe = [NSPipe pipe];
self.standardError = errorPipe;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(errorOccurred:)
name:NSFileHandleReadToEndOfFileCompletionNotification
object:[errorPipe fileHandleForReading]];
[[errorPipe fileHandleForReading] readToEndOfFileInBackgroundAndNotify];
[self launch];
[self waitUntilExit];
//Tear down
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void) setLaunchPath:(NSString *)launchPath
{
_launchTask = launchPath;
}
- (void) setArguments:(NSArray *)arguments
{
_arguments = arguments;
}
#end
I decided to use the composition approach and use NSTask inside my Task class, instead of inheritance, and it's working well.
Here is the updated class:
Task.h
#import <Foundation/Foundation.h>
#protocol TaskDelegate;
#interface Task : NSObject {
__weak id<TaskDelegate> _delegate;
NSTask *_processTask;
}
#property (weak, nonatomic) id<TaskDelegate> delegate;
#property (strong, nonatomic) NSString *name;
#property (strong, nonatomic) NSString *activityDescription;
//To be called just before launch
- (void) setupTask;
- (BOOL) processTaskConfigured;
//Launches the task - includes any setup required before the task is launched
- (void) launchAndWait;
//////////////////////////////////////////////////////////////////////////////////////////////// Process task delegation
#property (readonly) int terminationStatus;
- (BOOL) isRunning;
- (void) terminate;
#end
#protocol TaskDelegate <NSObject>
- (void) task:(Task *)task didReceiveTaskError:(NSString *)errorString;
#end
Task.m
#import "Task.h"
#import "NSData+Additions.h"
#interface Task ()
//Delegating to NSTask
#property (strong, nonatomic) NSTask *processTask;
#end
#implementation Task
- (id) init
{
self = [super init];
if (self) {
self.processTask = [NSTask new];
}
return self;
}
- (void) errorOccurred:(NSNotification *)notification {
if (_delegate) {
NSData *readData = [[notification userInfo] objectForKey:NSFileHandleNotificationDataItem];
NSString *outputString = [readData stringValue];
if (outputString.length)
[_delegate task:self didReceiveTaskError:outputString];
}
}
- (void) setupTask
{
//To be implemented by subclasses
}
- (BOOL) processTaskConfigured
{
return (_processTask.launchPath != nil);
}
//Process task conguration and execution is optional - if process task is not configured, this returns immediately
- (void) launchAndWait
{
if (!_processTask.launchPath)
return;
NSPipe *errorPipe = [NSPipe pipe];
_processTask.standardError = errorPipe;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(errorOccurred:)
name:NSFileHandleReadToEndOfFileCompletionNotification
object:[errorPipe fileHandleForReading]];
[[errorPipe fileHandleForReading] readToEndOfFileInBackgroundAndNotify];
[_processTask launch];
[_processTask waitUntilExit];
//Tear down
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
////////////////////////////////////////////////////////////////////////////////////////// Process task delegation
- (int) terminationStatus
{
if ([self processTaskConfigured]) {
return [_processTask terminationStatus];
}
return 0;
}
- (BOOL) isRunning
{
return [_processTask isRunning];
}
- (void) terminate
{
if ([self processTaskConfigured]) {
[_processTask terminate];
}
}
#end
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"]];
I have the excellent GCDAsyncSocket running perfectly on an iOS app I have developed.
I was just playing around with setting up a Mac OSX command line program that uses the library in a similar way to log to SQLite DB but can't get it to even attempt to connect to host. No errors get generated. The program doesn't crash or anything so don't have an idea about why it's not working. Does anyone have an idea why this won't work?
The console only prints out the following (with no connect/disconnect/read/write logging i.e. the socket delegate methods are not being called):
Attempting to connect to host: 192.168.1.2 on port: 1234 to refresh
Here is quite a bit of the code I am using:
main.m
#import <Foundation/Foundation.h>
#import "LoggerClass.h"
int main(int argc, const char * argv[]) {
#autoreleasepool {
LoggerClass *logger = [[LoggerClass alloc] init];
[logger startLogging];
while (logger.status == 0) {
sleep(1);
continue;
}
return 0;
}
}
LoggerClass.h
#import <Foundation/Foundation.h>
#import "Device.h"
#interface LoggerClass : NSObject <DeviceProtocol>
#property (nonatomic, strong) FMDatabase *database;
#property (nonatomic, strong) NSArray *devices;
#property (nonatomic) int status;
- (void)startLogging;
#end
LoggerClass.m
#import "LoggerClass.h"
#import "FMDatabase.h"
#define kLoggingInProgress 0
#define kLoggingCompleted 1
#implementation LoggerClass
#synthesize database = _database;
#synthesize devices = _devices;
#synthesize status = _status;
- (id)init {
if (self = [super init]) {
self.status = kLoggingInProgress;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsPath = [paths objectAtIndex:0];
NSString *path = [docsPath stringByAppendingPathComponent:#"database.sqlite"];
self.database = [FMDatabase databaseWithPath:path];
Device *d1 = [Device deviceWithName:#"Device 1" address:#"192.168.1.2" delegate:self];
self.devices = [NSArray arrayWithObjects:d1, nil];
}
return self;
}
- (void)startLogging {
for (Device *d in self.devices) {
[d refresh];
}
}
- (void)didUpdateDevice:(Device *)device {
// Insert DB entry code
NSLog(#"%# has finished Logging", device.name);
self.status = kLoggingCompleted; // This would obviously register completed if only 1 device returned but for sake of this test that fine
}
#end
Device.h
#import <Foundation/Foundation.h>
#import "GCDAsyncSocket.h"
#protocol DeviceProtocol;
#interface Device : NSObject
#property (nonatomic, weak) id<DeviceProtocol> delegate;
#property (nonatomic, strong) NSString *name;
#property (nonatomic, strong) NSString *address;
#property (nonatomic, strong) GCDAsyncSocket *socket;
+ (Device *)deviceWithName:(NSString *)n address:(NSString *)a delegate:(id<DeviceProtocol>)d;
- (void)refresh;
#end
#protocol DeviceProtocol <NSObject>
#required
- (void)didUpdateDevice:(Device *)device;
#end
Device.m
#import "Device.h"
#define DEVICE_PORT 1234
#implementation Device
#synthesize delegate = _delegate;
#synthesize name = _name;
#synthesize address = _address;
#synthesize socket = _socket;
- (id)initWithName:(NSString *)name andAddress:(NSString *)address andDelegate:(id<DeviceProtocol>)delegate { // Designated Initialiser
if (self = [super init]) {
self.socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
self.name = name;
self.address = address;
self.delegate = delegate;
}
return self;
}
+ (Device *)deviceWithName:(NSString *)n address:(NSString *)a delegate:(id<DeviceProtocol>)d {
return [[Device alloc] initWithName:n andAddress:a andDelegate:d];
}
#pragma mark - GCD Async Socket Delegate Methods
- (void)socket:(GCDAsyncSocket *)sender didConnectToHost:(NSString *)host port:(UInt16)port {
NSLog(#"Connected to: %#", self.address);
}
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)error {
NSLog(#"Socket for %# disconnected %#.", self.address, error);
if (self.delegate) [self.delegate didUpdateDevice:self];
}
- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag {
NSLog(#"socket:didWriteDataWithTag:");
}
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
NSLog(#"socket:didReadData:withTag:");
[self.socket disconnect];
}
- (void)refresh {
if ([self.address length] == 0) { [self.delegate didUpdateDevice:self]; return; }
NSLog(#"Attempting to connect to host: %# on port: %i to refresh", self.address, DEVICE_PORT);
NSError *error = nil;
if (![self.socket connectToHost:self.address onPort:DEVICE_PORT withTimeout:15 error:&error]) NSLog(#"ERROR: %#", error);
NSData *dataToSend;
// Build byte data here to send to device (exact same data works on iOS)
[self.socket writeData:dataToSend withTimeout:10 tag:0];
[self.socket readDataWithTimeout:-1 tag:0];
}
#end
I just re-read your comment and realized what your main() looks like. I think that's where your problem lies. The callbacks are probably sitting in the main dispatch queue but it never gets a chance to execute them. In a Cocoa application, the main queue normally runs as part of the main run loop, but you aren't starting a run loop.
See the dispatch_get_main_queue() documentation.
I think the simplest initial fix is to replace your spin loop with this:
dispatch_main();
I have downloaded this project from https://github.com/yahoo/yos-social-objc .
I have changed the ConsumerKey,
ConsumerSecret
and ApplicationId but When I Run the app it crashes. It gives an error of BAD-Excess.
Does anyone has any idea of this??
please advise
Thanks
Basically its just downloaded project from yahoo's developer's page still.
This is my Complete code
SocialSampleAppDelegate.h file
#import <UIKit/UIKit.h>
#import "YOSSession.h"
#class SocialSampleViewController;
#interface SocialSampleAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
SocialSampleViewController *viewController;
YOSSession *session;
NSMutableDictionary *oauthResponse;
BOOL launchDefault;
}
#property BOOL launchDefault;
#property (nonatomic, readwrite, retain) YOSSession *session;
#property (nonatomic, readwrite, retain) NSMutableDictionary *oauthResponse;
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet SocialSampleViewController *viewController;
- (void)getUserProfile;
- (void)createYahooSession;
- (void)handlePostLaunch;
#end
SocialSampleAppDelegate.m
#import "SocialSampleAppDelegate.h"
#import "SocialSampleViewController.h"
#import "YOSUser.h"
#import "YOSUserRequest.h"
#import "NSString+SBJSON.h"
#implementation SocialSampleAppDelegate
#synthesize window;
#synthesize viewController;
#synthesize session;
#synthesize launchDefault;
#synthesize oauthResponse;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after app launch
[window addSubview:viewController.view];
[window makeKeyAndVisible];
launchDefault = YES;
[self performSelector:#selector(handlePostLaunch) withObject:nil afterDelay:0.0];
}
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
launchDefault = NO;
if (!url) {
return NO;
}
NSArray *pairs = [[url query] componentsSeparatedByString:#"&"];
NSMutableDictionary *response = [NSMutableDictionary dictionary];
for (NSString *item in pairs) {
NSArray *fields = [item componentsSeparatedByString:#"="];
NSString *name = [fields objectAtIndex:0];
NSString *value = [[fields objectAtIndex:1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[response setObject:value forKey:name];
}
self.oauthResponse = response;
[self createYahooSession];
return YES;
}
- (void)handlePostLaunch
{
if(self.launchDefault) {
[self createYahooSession];
}
}
- (void)createYahooSession
{
// create session with consumer key, secret and application id
// set up a new app here: https://developer.yahoo.com/dashboard/createKey.html
// because the default values here won't work
self.session = [YOSSession sessionWithConsumerKey:#"MYConsumer KEy"
andConsumerSecret:#"MY Secret"
andApplicationId:#"My APPID"];
if(self.oauthResponse) {
NSString *verifier = [self.oauthResponse valueForKey:#"oauth_verifier"];
[self.session setVerifier:verifier];
}
BOOL hasSession = [self.session resumeSession];
if(!hasSession) {
[self.session sendUserToAuthorizationWithCallbackUrl:nil];
} else {
[self getUserProfile];
}
}
- (void)getUserProfile
{
// initialize the profile request with our user.
YOSUserRequest *userRequest = [YOSUserRequest requestWithSession:self.session];
// get the users profile
[userRequest fetchProfileWithDelegate:self];
}
- (void)requestDidFinishLoading:(YOSResponseData *)data
{
NSDictionary *userProfile = [[data.responseText JSONValue] objectForKey:#"profile"];
// NSLog(#"%#",[userProfile description]);
if(userProfile) {
[viewController setUserProfile:userProfile];
}
}
- (void)dealloc {
[viewController release];
[window release];
[super dealloc];
}
#end
SocialSampleViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
[nicknameLabel setText:#"loading..."];
}
- (void)setUserProfile:(NSDictionary *)data
{
NSString *welcomeText = [NSString stringWithFormat:#"Hey %# %#!",
[[data objectForKey:#"profile"] objectForKey:#"givenName"],
[[data objectForKey:#"profile"] objectForKey:#"familyName"]];
[nicknameLabel setText:welcomeText];
}
info plist
I am writing a code that reads data from a http connection and stores in a byte array.
I have written my own NSOperation class. Reference of the code is
Concurrent Operations Demystified
My HttpWorker class declaration is like
#interface HttpWorker : NSOperation{
NSString *param;
double requestCode;
BOOL isLive;
long initSleep;
BOOL _isFinished;
BOOL _isExecuting;
NSURL *_url;
NSURLConnection *_connection;
NSData *_data;
}
#property (nonatomic, retain) NSString *param;
#property (nonatomic) double requestCode;
#property (nonatomic) BOOL isLive;
#property (nonatomic) long initSleep;
#property (readonly) BOOL isFinished;
#property (readonly) BOOL isExecuting;
#property (readonly, copy) NSURL *url;
#property (nonatomic, retain) NSURLConnection *httpCon;
#property (readonly, retain) NSData *data;
-(id)initWithUrl:(NSURL *)_url;
-(void) setRequestParameters:(NSString *)parameters iRequestCode:(double)iRequestCode initialSleep:(long)initialSleep;
#end
And my HttpWorker.m class is like
#import "HttpWorker.h"
#import "Resources.h"
#implementation HttpWorker
#synthesize param;
#synthesize requestCode;
#synthesize isLive;
#synthesize initSleep;
#synthesize isFinished = _isFinished;
#synthesize isExecuting = _isExecuting;
#synthesize url = _url;
#synthesize data = _data;
-(id) initWithUrl: (NSURL *)Url{
self = [super init];
if(self == nil){
return nil;
}
_url = [Url copy];
_isExecuting = NO;
_isFinished = NO;
return self;
}
-(BOOL) isConcurrent{
return YES;
}
-(void) start{
if(![NSThread isMainThread]){
[self performSelectorOnMainThread:#selector(start) withObject:nil waitUntilDone:NO];
return;
}
[self willChangeValueForKey:#"isExecuting"];
_isExecuting = YES;
[self didChangeValueForKey:#"isExecuting"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:_url];
NSLog(#"Connecting... %#",_url);
_connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately: YES];
if(_connection == nil){
NSLog(#"connection is nil");
}
}
-(void) setRequestParameters:(NSString *)parameters iRequestCode:(double)iRequestCode initialSleep:(long)initialSleep {
self.param = parameters;
self.requestCode = iRequestCode;
self.initSleep = initialSleep;
}
/////////////////////////// delegate methods ///////////////////////////////
-(void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
NSLog(#"receieved response...");
_data = [[NSData alloc] init];
}
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)incomingData {
NSLog(#"receieved data...");
}
-(void) connectionDidFinishLoading:(NSURLConnection *) connection {
NSLog(#"connection did finish loading...");
}
#end
Problem is that when i run this code and add httpworker object to the NSOperationQueue, the code runs successfully and _connection is not nil but none of the delegate methods is executed. Can anyone please help?
Thanks and Best Regards...
Your delegate for the connection is "self" (= your NSOperation object). I assume this object is already gone when the connection wants to send messages to the delegate.
Your NSOperation does not have a "main" implementation. Consequently nothing will happen after the thread is started. It will (asynchronously!) fire the NSOperation and quit.
See:
http://developer.apple.com/mac/library/documentation/Cocoa/Reference/NSOperation_class/Reference/Reference.html#//apple_ref/occ/instm/NSOperation/main
Bottom line: I highly recommend ASIHTTPRequest for this kind of task.
http://allseeing-i.com/ASIHTTPRequest/