Pass the data in AppDelegate to Table View cell - ios

I need some help in passing data from AppDelegate to another controller which is a Table View Controller. In AppDelegate , i have a server response which i converted it to string. What i want is to pass that string to the another controller(Table View Controller) and display it to the Cell.
This my code in
AppDelegate.m
#import "AppDelegate.h"
#import "ChildListViewController.h"
#interface AppDelegate ()
#end
#implementation AppDelegate
{
#define URL2 #"http://192.168.1.166/bustracking/activation/validateActivationCode"
// NSMutableData *mutData;
// NSString *responseActCode;
// NSString *responseParentID;
// NSString *mess;
}
#synthesize responseActCode, responseParentID,mess,beaconID,Name,trackerID,lat,longi,Status,Image;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
UIUserNotificationSettings *settings =[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
return YES;
}
//get device token
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSString *device = [deviceToken description];
device = [device stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"<>"]];
device = [device stringByReplacingOccurrencesOfString:#" " withString:#""];
[[NSUserDefaults standardUserDefaults] setObject:device forKey:#"DeviceToken"];
[[NSUserDefaults standardUserDefaults] synchronize];
NSLog(#"My device is: %#", device);
}
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
{
NSLog(#"Failed to get token, error: %#", error);
}
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userPushInfo
{
application.applicationIconBadgeNumber = 0;
NSDictionary *fetchedDictionary =[userPushInfo objectForKey:#"aps"];
NSDictionary *fetchedDictionaryalert = [fetchedDictionary objectForKey:#"alert"];
NSDictionary *fetchedDictionarybody = [fetchedDictionaryalert objectForKey:#"body"];
NSDictionary *fetchedDictionaryactivation = [fetchedDictionarybody objectForKey:#"activation_code"];
if(fetchedDictionaryactivation != nil)
{
NSDictionary *fetchedDictionaryresult = [fetchedDictionaryactivation objectForKey:#"result"];
for (NSDictionary *user in fetchedDictionaryresult)
{
responseActCode = [user objectForKey:#"activation_code"];
responseParentID = [user objectForKey:#"parent_id"];
NSLog(#"Item actcode: %#", responseActCode);
NSLog(#"Item parentid: %#", responseParentID);
}
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:#"Activation Code"
message:(#"%#", responseActCode)
delegate:self
cancelButtonTitle: #"Ok"
otherButtonTitles: nil];
[alertView show];
alertView.tag = 0;
NSLog(#"dadadad %#", userPushInfo);
}
else
{
NSDictionary *fetchedDictionary =[userPushInfo objectForKey:#"aps"];
NSDictionary *fetchedDictionaryalert = [fetchedDictionary objectForKey:#"alert"];
NSDictionary *fetchedDictionarybody = [fetchedDictionaryalert objectForKey:#"body"];
NSDictionary *fetchedDictionaryresult = [fetchedDictionarybody objectForKey:#"result"];
//NSString *beaconID;
for (NSDictionary *user in fetchedDictionaryresult)
{
beaconID = [user objectForKey:#"beacon_id"];
mess = [user objectForKey:#"message"];
NSLog(#"Item actcode: %#", beaconID);
NSLog(#"Item parentid: %#", mess);
}
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:#""
message:(#"%#", mess)
delegate:self
cancelButtonTitle: #"Ok"
otherButtonTitles: nil];
[alertView show];
alertView.tag = 1;
NSLog(#"dadadad %#", userPushInfo);
}
}
-(void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger) buttonIndex
{
if (alertView.tag==0)
{
NSString *parentiD = responseParentID;
NSString *actcode = responseActCode;
NSString *beaconid = #"1458010000B0";
NSMutableURLRequest *request = nil;
NSString *getURL = [NSString stringWithFormat:#"%#?parent_id=%#&beacon_id=%#&activation_code=%#", URL2, parentiD, beaconid, actcode];
getURL = [getURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString: getURL];
request = [NSMutableURLRequest requestWithURL:url];
NSLog(#"link: %#", getURL);
[request setHTTPMethod:#"GET"];
[request addValue: #"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
NSLog(#"connection: %#", connection);
if( connection )
{
mutData = [NSMutableData new];
}
else
{
NSLog (#"NO_CONNECTION");
return;
}
}
else if(alertView.tag == 1)
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
ChildListViewController *childcheck = (ChildListViewController *)[storyboard instantiateViewControllerWithIdentifier:#"ChildStoryBoard"];
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
childcheck.childNameData =[_childNameData objectAtIndex:indexPath.row];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window setRootViewController:childcheck];
[self.window makeKeyAndVisible];
NSLog (#"Move to next View controller");
}
}
#pragma mark NSURLConnection delegates
-(void) connection:(NSURLConnection *) connection didReceiveResponse:(NSURLResponse *)response
{
[mutData setLength:0];
}
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[mutData appendData:data];
}
-(void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
return;
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
/*NSString *responseStringWithEncoded = [[NSString alloc] initWithData: mutData encoding:NSUTF8StringEncoding];
NSLog(#"Response from Server : %#", responseStringWithEncoded);
*/
NSError *error = nil;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:mutData options:kNilOptions error:&error];
NSArray *fetchedArr = [json objectForKey:#"child_info"];
for (NSDictionary *user in fetchedArr)
{
beaconID = [user objectForKey:#"beacon_id"];
Name = [user objectForKey:#"name"];
trackerID = [user objectForKey:#"tracker_id"];
lat = [user objectForKey:#"latitude"];
longi = [user objectForKey:#"longitude"];
Status = [user objectForKey:#"status"];
Image = [user objectForKey:#"image"];
NSLog(#"Item beacID: %#", beaconID);
NSLog(#"Item nam: %#", Name);
NSLog(#"Item trackID: %#", trackerID);
NSLog(#"Item lati: %#", lat);
NSLog(#"Item longi: %#", longi);
NSLog(#"Item stat: %#", Status);
NSLog(#"Item ima: %#", Image);
//NSLog(#"Item parentid: %#", [user objectForKey:#"parent_id"]);
//NSLog(#"Item actcode: %#", [user objectForKey:#"activation_code"]);
}
//NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
//[defaults setObject:responseActCode forKey:#"HighScore"];
//[defaults synchronize];
//NSLog(#"from data: %#", [defaults objectForKey:#"HighScore"]);
}
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
//Name = [[NSString alloc]init];
}
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
#end
AppDelegate.h
#import <UIKit/UIKit.h>
#import "ChildListViewController.h"
#interface AppDelegate : UIResponder <UIApplicationDelegate>
{
NSMutableData *mutData;
NSString *responseActCode;
NSString *responseParentID;
NSString *mess;
NSString *beaconID;
NSString *Name;
NSString *Status;
NSString *Image;
NSString *trackerID;
NSString *lat;
NSString *longi;
}
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) NSString *responseActCode;
#property (strong, nonatomic) NSString *responseParentID;
#property (strong, nonatomic) NSString *mess;
#property (readonly) NSString *beaconID;
#property (readonly) NSString *Name;
#property (readonly) NSString *trackerID;
#property (readonly) NSString *lat;
#property (readonly) NSString *longi;
#property (readonly) NSString *Status;
#property (readonly) NSString *Image;

U can try this, i'm not sure if it work but hope it help
In AppDelegate.h: Add property to that stuff u want to pass, eg. #property (strong, nonatomic) NSString *string;
In AppDelegate.m: Assign value to it
In YourVC.m:
#import "AppDelegate.h"
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSString *yourString = [appDelegate string];

You have your data in Appdelegate now. Just create an object of it in file(Table view for you) where you need data and you can access your data now anywhere you want in that project.
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSlog(#"appDelegate.fechedArray==%#",appDelegate.fechedArray);

in AppDelegate.h
#define XAppDelegate ((AppDelegate *)[[UIApplication sharedApplication] delegate])
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#end
and now you can access to your AppDelegate everywhere like this :
XAppDelegate.something

Related

Obj-C UITable not populating with MutableArray

I have an array that loads when the app starts and it gets the correct data and fills the array but once I go to the tableviewcontroller it says the array is null.
This is where I get the data
AppDelegate.h
#interface AppDelegate : UIResponder <UIApplicationDelegate>
{
NSMutableArray *tableDicsArrayTickets;
NSMutableArray *dictionaryStack;
NSMutableString *textInProgress;
NSError *errorPointer;
}
#property (strong, nonatomic) NSMutableArray *tableDicsArrayTickets;
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) NSString *photo_URL;
+(NSDictionary *)dictionaryForXMLData:(NSData *)data error:(NSError **)errorPointer;
+(NSDictionary *)dictionaryForXMLString:(NSString *)string error:(NSError **)errorPointer;
+(AppDelegate *) getInstance;
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
self.tableDicsArrayTickets = [[NSMutableArray alloc] init];
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration:defaultConfigObject delegate:nil delegateQueue:[NSOperationQueue mainQueue]];
NSURL *url = [NSURL URLWithString:#"http://MYURLexample.php"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSString *deviceCode = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
NSString *post = [[NSString alloc] initWithFormat:#"parameter=%#", deviceCode];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:[post dataUsingEncoding:NSUTF8StringEncoding]];
NSURLSessionDataTask *dataTask = [defaultSession dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(#"Response:%# %#\n", response, error);
if(error == nil)
{
NSString *text =[[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
NSLog(#"Data = %#",text);
NSDictionary *dics = [[NSDictionary alloc]initWithDictionary:[AppDelegate dictionaryForXMLString:text error:nil]];
NSLog(#"dics is %#", dics);
[self.tableDicsArrayTickets addObject:[[dics valueForKey:#"response"] valueForKey:#"text"]];
NSLog(#"Array2 is %#", self.tableDicsArrayTickets);
}
}];
[dataTask resume];
ViewController.h
#interface HistoryViewController : UIViewController<UITableViewDataSource, UITableViewDelegate>
{
AppDelegate *mainDelegate;
}
#property (strong, nonatomic) AppDelegate *mainDelegate;
ViewController.m
#pragma
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [mainDelegate.tableDicsArrayTickets count];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 60;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSMutableArray *array = mainDelegate.tableDicsArrayTickets;
NSString *cellIdentifier = #"Cell";
PhotoTableViewCell *cell = (PhotoTableViewCell *) [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell == nil)
{
cell = [[PhotoTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
NSLog(#"Array is %#", [[array objectAtIndex:indexPath.row] objectForKey:#"text"]);
cell.ticketNumber.text = [[array objectAtIndex:indexPath.row] objectForKey:#"text"];
return cell;
}
Im not having a problem getting the data for the array its just once I finally go to the view controller with the table on it the array becomes null.
I think you're doing a number of things wrong...
First:
// AppDelegate.h
#interface AppDelegate : UIResponder <UIApplicationDelegate>
{
// this should NOT be here
NSMutableArray *tableDicsArrayTickets;
NSMutableArray *dictionaryStack;
NSMutableString *textInProgress;
NSError *errorPointer;
}
#property (strong, nonatomic) NSMutableArray *tableDicsArrayTickets;
// ...
That should give you a compile warning:
autosynthesized property 'tableDicsArrayTickets' will use synthesized instance
variable '_tableDicsArrayTickets', not existing instance variable 'tableDicsArrayTickets'
Same with:
//HistoryViewController.h
#interface HistoryViewController : UIViewController<UITableViewDataSource, UITableViewDelegate>
{
// this should NOT be here
AppDelegate *mainDelegate;
}
#property (strong, nonatomic) AppDelegate *mainDelegate;
Which should give you:
autosynthesized property 'mainDelegate' will use synthesized instance
variable '_mainDelegate', not existing instance variable 'mainDelegate'
Then, you're not showing where you have this in HistoryViewController.m (should probably be in viewDidLoad()):
_mainDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];

Pass json response to another view controller in iOS

At first i just send data to server using GET method, I receive a response like below
2015-11-16 14:21:42.168 smartschool[1963:348015] Item actcode: ZQRTNN68
2015-11-16 14:21:42.169 smartschool[1963:348015] Item parentid: 8
How can i display the activation code to a label of the next viewController.
Here is my code:
#import "RegistrationViewController.h"
#interface RegistrationViewController ()
#end
#implementation RegistrationViewController
{
NSMutableData *mutableData;
#define URL #"http://192.168.1.166/bustracking/activation/requestActivationCode"
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
-(IBAction)sendDataUsingGet:(id)sender{
[self sendDataToServer : #"GET"];
}
-(void) sendDataToServer : (NSString *) method
{
NSString *parentName = parent_name.text;
NSString *contactNumber = contact_number.text;
NSString *beaconid = #"145801000095";
//NSString *beaconMacAdd = #"14:58:01:00:00:95";
if(parentName.length > 0 && contactNumber.length > 0){
NSLog (#"Getting response from server...");
NSMutableURLRequest *request = nil;
// Only Difference between POST and GET is only in the way they send parameters
if([method isEqualToString:#"GET"]){
NSString *getURL = [NSString stringWithFormat:#"%#?parent_name=%#&contact_number=%#&beacon_id=%#", URL, parentName, contactNumber, beaconid];
//url = [NSURL URLWithString: getURL];
getURL = [getURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString: getURL];
request = [NSMutableURLRequest requestWithURL:url];
NSLog(#"urlinfo: %#", url);
NSLog(#"link: %#", getURL);
}
[request setHTTPMethod:method];
[request addValue: #"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
NSLog(#"connection: %#", connection);
if( connection )
{
mutableData = [NSMutableData new];
}
else
{
NSLog (#"NO_CONNECTION");
return;
}
}
else
{
NSLog(#"NO_VALUES");
}
}
#pragma mark NSURLConnection delegates
-(void) connection:(NSURLConnection *) connection didReceiveResponse:(NSURLResponse *)response
{
[mutableData setLength:0];
}
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[mutableData appendData:data];
}
-(void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog (#"NO_CONNECTION");
return;
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSError *error = nil;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:mutableData options:kNilOptions error:&error];
NSArray *fetchedArr = [json objectForKey:#"response"];
NSString *responseActCode;
for (NSDictionary *user in fetchedArr)
{
responseActCode = [user objectForKey:#"activation_code"];
NSLog(#"Item actcode: %#", responseActCode);
NSLog(#"Item parentid: %#", [user objectForKey:#"parent_id"]);
//NSLog(#"Item actcode: %#", [user objectForKey:#"activation_code"]);
}
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:responseActCode forKey:#"HighScore"];
[defaults synchronize];
NSLog(#"from data: %#", [defaults objectForKey:#"HighScore"]);
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Activation Code"
message:(#"%#", responseActCode)
delegate:nil //or self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
#end
If the returning data is in dictionary format, declare nsdictionary in header.h class on which you wan to transfer data, similarly you can use array and string, now if you are using a storyboard, below is the method.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Make sure your segue name in storyboard is the same as this line
if ([[segue identifier] isEqualToString:#"YOUR_SEGUE_NAME_HERE"])
{
// Get reference to the destination view controller
YourViewController *vc = [segue destinationViewController];
// Pass any objects to the view controller here, like...
vc.dictionary = self.dictionary.
}
}
and you want to transfer data upon cell tap this is what you have to do.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:#"YOUR_SEGUE_NAME_HERE"" sender:self];
}
When "performSegueWithIdentifier" is called, this method automatically redirected to "prepareForSegue" method:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSIndexPath *indexPath= [self.tableView indexPathForSelectedRow];
// Make sure your segue name in storyboard is the same as this line
if ([[segue identifier] isEqualToString:#"YOUR_SEGUE_NAME_HERE"])
{
// Get reference to the destination view controller
YourViewController *vc = [segue destinationViewController];
// Pass any objects to the view controller here, like...
now this time its array.
vc.array= [array[indexpath.row] valueforkey#"jsonkey"];
}
}
There are many ways to pass data between view controllers. Here's one example:
Create a public property in "SomeViewController" class(eg: responseActCodeString) and set that property to your activation code(eg: responseActCode).
SomeViewController *someViewController = [[SomeViewController alloc] initWithNib:#"SomeViewController " bundle:nil];
someViewController.responseActCodeString = responseActCode;
[self pushViewController:someViewController animated:YES];
You can also use notifications, user defaults as an alternatives.
Also look at this link.
For storyboards add following method in initial view controller:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"someIdentifier"]){
SomeViewController*someViewController= (SomeViewController*)segue.destinationViewController;
someViewController.responseActCodeString = responseActCode;
}
}

Code keeps crashing with passing data

I'm building my first iOS app with a login system. I've built some simple things before, but this is on a whole new level. Currently I'm able to login and get some data back from the server. The app then performs a model segue to MainView with MainController attached to it.
When I log in, the app gets token and success back from the server. This token is needed for further requests to the server. However, I can't seem to figure out how to pass the token to MainController. It doesn't matter what I try, the app crashes with an unknown error.
Right now - with the code below - it throws:
2014-10-11 14:30:14.077 LoginScreen[29076:4688502] -[UINavigationController setXAuthToken:]: unrecognized selector sent to instance 0x7bfd1140
2014-10-11 14:30:14.104 LoginScreen[29076:4688502] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UINavigationController setXAuthToken:]: unrecognized selector sent to instance 0x7bfd1140'
ViewController.h
#import <UIKit/UIKit.h>
#import "MainController.h"
#interface ViewController : UIViewController <UITextFieldDelegate>
#property (weak, nonatomic) IBOutlet UITextField *txtUsername;
#property (weak, nonatomic) IBOutlet UITextField *txtPassword;
- (IBAction)sigininClicked:(id)sender;
- (IBAction)backgroundTap:(id)sender;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)sigininClicked:(id)sender {
NSInteger success = 0;
#try {
if([[self.txtUsername text] isEqualToString:#""] || [[self.txtPassword text] isEqualToString:#""] ) {
[self alertStatus:#"Please enter Email and Password" :#"Sign in Failed!" :0];
} else {
NSString *post =[[NSString alloc] initWithFormat:#"username=%#&password=%#",[self.txtUsername text],[self.txtPassword text]];
NSLog(#"PostData: %#",post);
NSURL *url=[NSURL URLWithString:#"http://www.mywebsite.com/auth"];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)[postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
//[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[url host]];
NSError *error = [[NSError alloc] init];
NSHTTPURLResponse *response = nil;
NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSLog(#"Response code: %ld", (long)[response statusCode]);
if ([response statusCode] >= 200 && [response statusCode] < 300)
{
NSString *responseData = [[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];
NSLog(#"Response ==> %#", responseData);
NSError *error = nil;
NSDictionary *jsonData = [NSJSONSerialization
JSONObjectWithData:urlData
options:NSJSONReadingMutableContainers
error:&error];
success = [jsonData[#"success"] integerValue];
NSLog(#"Success: %ld",(long)success);
if(success == 1)
{
NSLog(#"Login SUCCESS");
} else {
NSString *error_msg = (NSString *) jsonData[#"error_message"];
[self alertStatus:error_msg :#"Sign in Failed!" :0];
}
} else {
//if (error) NSLog(#"Error: %#", error);
[self alertStatus:#"Connection Failed" :#"Sign in Failed!" :0];
}
}
}
#catch (NSException * e) {
NSLog(#"Exception: %#", e);
[self alertStatus:#"Sign in Failed." :#"Error!" :0];
}
if (success) {
[self performSegueWithIdentifier:#"login_success" sender:self];
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"login_success"]) {
MainController *controller = (MainController *)segue.destinationViewController;
controller.xAuthToken = #"test string";
}
}
- (void) alertStatus:(NSString *)msg :(NSString *)title :(int) tag
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title
message:msg
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil, nil];
alertView.tag = tag;
[alertView show];
}
- (IBAction)backgroundTap:(id)sender {
[self.view endEditing:YES];
}
-(BOOL) textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
#end
MainController.h
#import <Foundation/Foundation.h>
#interface MainController : UIViewController
#property (nonatomic,strong) NSString *xAuthToken;
#end
MainController.m
#import "MainController.h"
#interface MainController ()
#end
#implementation MainController
- (void)viewDidLoad
{
NSLog(#"%#",_xAuthToken);
}
#end
The stack trace tells you what the problem is - you are trying to set the XAuthToken property on a UINavigationController - but a UINavigationController doesn't have that property.
Your MainController instance is embedded in a UINavigationController, so that is what you get from destinationViewController in prepareForSegue.
You need to access the view controller stack -
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"login_success"]) {
UINavigationController *navController = (UINavigationController *)segue.destinationViewController;
MainController *controller = (MainController *)navController.topViewController
controller.xAuthToken = #"test string";
}
}

Google Translate API on iPhone

I am writing a simple code, in which I am using Google API for translation services, but I am getting the following error:
Connection failed: Error Domain=NSURLErrorDomain Code=-1000 "bad URL" UserInfo=0x176c80a0 {NSUnderlyingError=0x175c8d00 "bad URL", NSLocalizedDescription=bad URL}
This is the code I have written:
#import "ViewController.h"
#import"SBJson.h"
#interface ViewController ()
#property (strong, nonatomic) IBOutlet UITextField *textfield;
#property (strong, nonatomic) IBOutlet UIButton *go;
#property (strong, nonatomic) IBOutlet UITextView *textview;
- (IBAction)translate:(id)sender;
#property (strong, nonatomic) NSMutableArray *translations;
#property (strong, nonatomic)NSString *_lastText;
#property (nonatomic, copy) NSString * lastText;
#end
#implementation ViewController
#synthesize lastText = _lastText;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//Initializing the translation array
_translations = [[NSMutableArray alloc] init];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)performTranslation {
responseData = [[NSMutableData data] init ];
NSString *langString = #"en|ja";
NSString *textEscaped = [_lastText
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *langStringEscaped = [langString
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
//My_Key=Google generated key
NSString *url = [NSString stringWithFormat:#"https://www.googleapis.com/language/translate/v2?
key={My_key}&source=en&target=de&q=%#",textEscaped];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
}
- (IBAction)translate:(id)sender {
[_translations removeAllObjects];
[_textfield resignFirstResponder];
_go.enabled=NO;
self.lastText = _textfield.text;
[_translations addObject:_lastText];
_textview.text = _lastText;
[self performTranslation];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[responseData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[responseData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
_textview.text = [NSString stringWithFormat:#"Connection failed: %#", [error description]];
_go.enabled = YES;
NSLog([NSString stringWithFormat:#"Connection failed: %#", [error description]]);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *responseString = [[NSString alloc] initWithData:responseData
encoding:NSUTF8StringEncoding];
NSMutableDictionary *luckyNumbers = [responseString JSONValue];
if (luckyNumbers != nil) {
NSDecimalNumber * responseStatus = [luckyNumbers objectForKey:#"responseStatus"];
if ([responseStatus intValue] != 200) {
_go.enabled = YES;
return;
}
NSMutableDictionary *responseDataDict = [luckyNumbers objectForKey:#"responseData"];
if (responseDataDict != nil) {
NSString *translatedText = [responseDataDict objectForKey:#"translatedText"];
[_translations addObject:translatedText];
self.lastText = translatedText;
_textview.text = [_textview.text stringByAppendingFormat:#"\n%#", translatedText];
_go.enabled = YES;
}
}
}
#end
The problem is like it says. The URL has been generated incorrectly. Try:
NSString * source = #"en";
NSString * target = #"ja";
NSString * key = #"YOUR-KEY";
NSString * url = [NSString stringWithFormat:#"https://www.googleapis.com/language/translate/v2?key=%#&source=%#&target=%#",key,source,target];
and see what response you get.
You can just use FGTranslator. Simple.
FGTranslator *translator = [[FGTranslator alloc] initWithGoogleAPIKey:#"your_google_key"];
[translator translateText:#"Bonjour!"
completion:^(NSError *error, NSString *translated, NSString *sourceLanguage)
{
if (error)
NSLog(#"translation failed with error: %#", error);
else
NSLog(#"translated from %#: %#", sourceLanguage, translated);
}];

Can't reload data in tableView after parsing XML

I'm starting NSURLConnection, parsing XML, initialize array from this XML, and show it in the tableView. In connectionDidFinishLoading I'm trying [self.tableView reloadData, but it doesn't work. This is my code:
my .h file:
#interface catalogViewController : UITableViewController //
#property (nonatomic, strong) NSMutableData *receivedData;
#property (nonatomic,retain) NSArray * titleArr;
#property (nonatomic,retain) NSArray * contentArr;
#property (nonatomic,retain) NSArray * ImageURLArr;
#property (nonatomic,retain) NSArray * dateArr;
#property (nonatomic,retain) NSArray * priceArr;
#property (nonatomic,retain) NSDictionary * xmlDictionary;
#property (nonatomic,retain) NSArray * IDArr;
#property (nonatomic) BOOL * didDataLoaded;
#property (strong, nonatomic) IBOutlet UITableView *myTableView;
#end
My .m file:
#import "catalogViewController.h"
#import "XMLReader.h"
#interface catalogViewController ()
#end
#implementation catalogViewController
- (id)initWithStyle:(UITableViewStyle)style {
self = [super initWithStyle:style];
if (self) { } return self;
}
//-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-CONNECTIONS METHOD START-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[_receivedData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[_receivedData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[connection release];
[_receivedData release];
NSString *errorString = [[NSString alloc] initWithFormat:#"Connection failed! Error - %# %# %#", [error localizedDescription], [error description], [[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]]; NSLog(#"%#",errorString);
[errorString release];
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-GET FULL DATA HERE-=-=-=-=-=-=-=-=--=-=-=-=-=-=-
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *dataString = [[NSString alloc] initWithData:_receivedData encoding:NSUTF8StringEncoding];
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-XMLPARSER PART START-=-=-=-=-=-=-=-=-=-=-=-=-=-=- //
NSString *testXMLString = [NSString stringWithContentsOfURL:myURL usedEncoding:nil error:nil];
// -=-=-=-=-=-=-=-=-=-=Parse the XML into a dictionary-=-=-=-=-=-=-=-=-=-=
NSError *parseError = nil;
_xmlDictionary = [XMLReader dictionaryForXMLString:testXMLString error:&parseError];
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-XMLPARSER PART END-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
_titleArr =[[[_xmlDictionary objectForKey:#"result"] objectForKey:#"name"] valueForKey:#"text"];
_IDArr =[[[_xmlDictionary objectForKey:#"result"] objectForKey:#"id"] valueForKey:#"text"];
_priceArr=[[[_xmlDictionary objectForKey:#"result"] objectForKey:#"price"] valueForKey:#"text"];
_ImageURLArr=[[[_xmlDictionary objectForKey:#"result"] objectForKey:#"img"] valueForKey:#"text"];
[connection release];
[_receivedData release];
[dataString release];
_didDataLoaded=TRUE;
[_myTableView reloadData]; // IBOutlet property
[self.tableView reloadData]; //default
}
//-=-=-=-=-=-=-=-=-=-=-Connection methods END-=-=-=-=-=-=-=-=-=-
- (void)viewDidLoad {
[super viewDidLoad];
_didDataLoaded=FALSE;
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-XMLPARSER PART START-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//-=-==-=-=-=-=-=-=-=-=-=-=--=-=START Shit with connection-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=
NSString* params = #"request_params";
NSURL* url = [NSURL URLWithString:#"my URL"];
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:15.0];
[request addValue:#"text/xml; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
request.HTTPMethod = #"POST";
request.HTTPBody = [params dataUsingEncoding:NSUTF8StringEncoding];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if (connection) {
NSLog(#"Connecting...");
_receivedData = [[NSMutableData data] retain];
} else {
NSLog(#"Connecting error");
}
}
//-=-==-=-=--=-==-=-=-=-=-=--=-==---=-=--==-=-=-=-=-TableView methods-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=--=-=-=-=-=-=-=
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (_didDataLoaded == FALSE) {
return 1;
}
else return self.titleArr.count;
}
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView { return 1; }
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"creatures"];
UIImage *creatureImage = nil;
if (_didDataLoaded == FALSE) {
cell.textLabel.text=#"Downloading...";
cell.detailTextLabel.text= #"downloading...";
} else {
cell.textLabel.text = [self.titleArr objectAtIndex:indexPath.row];
cell.detailTextLabel.text= _IDArr[indexPath.row];
NSString *img = self.ImageURLArr[indexPath.row];
creatureImage =[[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:img]]]; cell.imageView.image = creatureImage;
}
return cell;
}
#end
XML downloading - OK, parsing - OK, initialising arrays - OK. But when I start project I have exception on the line NSLog(#"%#", self.titleArr objectAtIndex:indexPath.row]; - says: "Thread 1: EXC_BAD_ACCESS (code 1)
How can I understand it's means that it's trying initialize array when it's not prepare. My problem is i can't delay tableView methods or what? How can i fix it? I'm trying fix itfor some days...
Your titleArr is deallocated from memory and then you are requesting object of it so it is giving you a crash. So allocate memory to array by this way.
_titleArr = [[NSArray alloc] initWithArray:[[[_xmlDictionary objectForKey:#"result"] objectForKey:#"name"] valueForKey:#"text"]];
Eventhough it's not recommended way but the following can provide a solution to you
self.tableView.delegate = nil;
self.tableView.datasource = nil;
and when safely your array was populated with the xml data set back to
self.tableView.delegate = self;
self.tableView.datasource = self;

Resources