I can't receive XML file from Weather Underground service - iphone

I'm trying to write a weather app that use wunderground api...
I've got an apiKey and I used it in the code below, but I can't see any result in debug area...
Xcode show me a warning in a line "EXPRESSION RESULT UNUSED"...Is this the problem?
Can anybody help me please?
#import "WeatherForecast.h"
#import "MainViewController.h"
#implementation WeatherForecast
- (void) queryServiceWithState:(NSString *)state
andCity:(NSString *)city
withParent:(UIViewController *)controller {
viewController = (MainViewController *)controller;
responseData = [NSMutableData data];
apiKey = #"c5f79118382c6e91";
NSString *url =
[NSString stringWithFormat:
#"http://api.wunderground.com/api/%#/conditions/q/%#//%#.xml",
apiKey, state, city];
theURL = [NSURL URLWithString:url];
NSURLRequest *request = [NSURLRequest requestWithURL:theURL];
[[NSURLConnection alloc] initWithRequest:request delegate:self];//EXPRESSION RESULT UNUSED
}
#pragma mark NSURLConnection Delegate Methods
- (NSURLRequest *)connection:(NSURLConnection *)connection
willSendRequest:(NSURLRequest *)request
redirectResponse:(NSURLResponse *)response{
#autoreleasepool {
theURL = [request URL];
}
return request;
}
- (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 {
NSLog(#"Error = %#",error);
}
- (void)connectionDidFinishiLoading: (NSURLConnection *)connection {
NSString *content =
[[NSString alloc]initWithBytes:[responseData bytes]
length:[responseData length]
encoding:NSUTF8StringEncoding];
NSLog ( #"Data = %#",content);
//...Insert code to parse the content here...
[viewController updateView];
}
#end
I've got another 2 .m files for my app, maybe the error is in one of this
#import "MainViewController.h"
#import "WeatherForecast.h"
#interface MainViewController ()
#end
#implementation MainViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self refreshView:self];
}
- (IBAction)refreshView:(id)sender {
[loadingActivityIndicator startAnimating];
[self.forecast queryServiceWithState:#"UK" andCity:#"London" withParent:self];
}
- (void)updateView {
//...
[loadingActivityIndicator stopAnimating];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Flipside View
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller
{
[self dismissViewControllerAnimated:YES completion:nil];
}
- (IBAction)showInfo:(id)sender
{
FlipsideViewController *controller = [[FlipsideViewController alloc]
initWithNibName:#"FlipsideViewController" bundle:nil];
controller.delegate = self;
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentViewController:controller animated:YES completion:nil];
}
#end
And
#import "AppDelegate.h"
#import "WeatherForecast.h"
#import "MainViewController.h"
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:
(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.mainViewController = [[MainViewController alloc]
initWithNibName:#"MainViewController" bundle:nil];
WeatherForecast *forecast = [[WeatherForecast alloc] init];
self.mainViewController.forecast = forecast;
self.window.rootViewController = self.mainViewController;
[self.window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
}
- (void)applicationWillTerminate:(UIApplication *)application
{
}
#end
If I try to turn off internet connection I can see in the debug area the "Error message", but if I turn on internet connection, so I only see the Activity Indicator spinning forever...
Thank you for your response....I feel lost...

Where you get EXPRESSION RESULT UNUSED is the connection object. You should usually be storing that into a property so you ensure that it isn't destroyed while you're still using it.

Related

How do you get the NSURLConnection delegate methods to trigger?

I can't seem to get the delegate methods to call, when I load the view associated with this class.. none of them fire. I'm sure it's something that I've overlooked but I can't for the life of me figure out why.
DownloadUpdates.h
#import <UIKit/UIKit.h>
#interface DownloadUpdates : UIViewController
#property (strong, nonatomic) NSMutableData *responseData;
#property (strong, nonatomic) NSURLConnection *connection;
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
#end
DownloadUpdates.m
The URL has been removed for privacy purposes, but it's just making a call to an API which will be returning JSON data. This URL functions as expected so it's an issue with the code.
#import "DownloadUpdates.h"
#interface DownloadUpdates ()
#end
#implementation DownloadUpdates
- (void)connection:(NSURLConnection *)_connection didReceiveResponse:(NSURLResponse *)response
{
_responseData = [[NSMutableData alloc] init];
NSLog(#"Response received");
}
- (void)connection:(NSURLConnection *)_connection didReceiveData:(NSData *)data
{
[_responseData appendData:data];
NSLog(#"Data received");
}
- (void)connection:(NSURLConnection *)_connection didFailWithError:(NSError *)error
{
NSLog(#"Unable to fetch data");
}
- (void)connectionDidFinishLoading:(NSURLConnection *)_connection
{
NSLog(#"Succeeded! Received %d bytes of data",[_responseData
length]);
// NSString *txt = [[NSString alloc] initWithData:_responseData encoding: NSASCIIStringEncoding];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSURL *myURL = [NSURL URLWithString:#"URL HERE"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:myURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60];
_connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I'd appreciate any help / advice you can offer.
Use the properties to apply the strong modifier:
self.responsedata = [[NSMutableData alloc] init];
(.....)
self.connection = [[NSURLConnection alloc] initWithRequest: ....etc...
I'd suggest putting a NSLog or breakpoint in viewDidLoad to make sure this is getting called at all. For example, this might happen if you neglected to specify DownloadUpdates as the class for your storyboard scene.

Appending data from downloaded from the web in NSMutableData

I'm trying to append data from a CSV file that I'm getting form the internet. Something is going wrong and I can't figure out what. My log is not returning anything for "Field" or "Value". I'm holding the data as NSMutableData and trying to append it. Am I overwriting it in any way? Something in the data storage/retrieval process must be going wrong... Could you pls take a look at this code and tell me if I'm doing something wrong:
#import "ViewController.h"
#import "CHCSVParser.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize parser = _parser;
bool isStatus;
#synthesize apendData;
-(void) connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(#"connectionDidFinishLoading");
NSString *myString;
myString = [[NSString alloc] initWithData: apendData encoding:NSUTF8StringEncoding];
_parser = [[CHCSVParser alloc] initWithContentsOfCSVFile:[NSHomeDirectory() stringByAppendingPathComponent:myString]];
_parser.delegate = self;
[_parser parse];
}
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSLog(#"data: %#", data);
if (apendData)
[apendData appendData:data];
else
apendData = [[NSMutableData alloc] initWithData:data];
}
- (void)loadDatafromURL
{
NSURL *url = [NSURL URLWithString:#"http://www.google.com/trends/trendsReport?hl=en-US&cat=0-13&date=today%207-d&cmpt=q&content=1&export=1"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection connectionWithRequest:request delegate:self];
}
- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
NSLog(#"%#", [error description]);
}
- (void)parser:(CHCSVParser *)parser didBeginLine:(NSUInteger)recordNumber
{
if (recordNumber == 41) {
isStatus = YES;
NSLog(#"ParsingStart..."); // Not getting this
}
}
- (void)parser:(CHCSVParser *)parser didEndLine:(NSUInteger)recordNumber
{
if (recordNumber == 50) {
NSLog(#"ParsingEnd..."); // Not getting this
[parser cancelParsing];
}
}
- (void)parser:(CHCSVParser *)parser didReadField:(NSString *)field atIndex:(NSInteger)fieldIndex
{
if ((isStatus = YES)) {
NSLog(#"YES is working");
if (fieldIndex == 0) {
NSLog(#"Field = %#", field); // Just getting "Field = "
}
if (fieldIndex == 1){
NSLog(#"Value = %#", field); // Not getting this
}
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self loadDatafromURL];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#end

iOS: foursquare request fails

I am assigned to work with foursquare just recently. I have an app that needs to be authenticated and access the foursquare environment. I am having trouble with the following code to access checkins. I had already successfully made the authentication but the thing is that when I made a check in request, an errorType invalid_auth code 401 appears. I just don't know what's wrong with this.
Here is my full code; I am using fsq wrapper I found in github:
#import "FSQViewController.h"
#define kClientID #"XXXXXXXXXXXXXXXXXXXXXXX"
#define kCallbackURL #"invitation://foursquare"
#interface FSQViewController()
#property(nonatomic,readwrite,strong) BZFoursquare *foursquare;
#property(nonatomic,strong) BZFoursquareRequest *request;
#property(nonatomic,copy) NSDictionary *meta;
#property(nonatomic,copy) NSArray *notifications;
#property(nonatomic,copy) NSDictionary *response;
#end
#implementation FSQViewController
#synthesize foursquare = foursquare_;
#synthesize request = request_;
#synthesize meta = meta_;
#synthesize notifications = notifications_;
#synthesize response = response_;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - View lifecycle
- (id) initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];
if(self){
self.foursquare = [[BZFoursquare alloc]initWithClientID:kClientID callbackURL:kCallbackURL];
foursquare_.version = #"20120206";
foursquare_.locale = [[NSLocale currentLocale]objectForKey:NSLocaleLanguageCode];
foursquare_.sessionDelegate = (id<BZFoursquareSessionDelegate>) self;
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#pragma mark -
#pragma mark BZFoursquareRequestDelegate
- (void)requestDidFinishLoading:(BZFoursquareRequest *)request {
NSLog(#"test");
self.meta = request.meta;
self.notifications = request.notifications;
self.response = request.response;
self.request = nil;
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
- (void)request:(BZFoursquareRequest *)request didFailWithError:(NSError *)error {
NSLog(#"HERE > %s: %#", __PRETTY_FUNCTION__, error);
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:[[error userInfo] objectForKey:#"errorDetail"] delegate:nil cancelButtonTitle:NSLocalizedString(#"OK", #"") otherButtonTitles:nil];
[alertView show];
self.meta = request.meta;
self.notifications = request.notifications;
self.response = request.response;
self.request = nil;
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
#pragma mark -
#pragma mark BZFoursquareSessionDelegate
- (void)foursquareDidAuthorize:(BZFoursquare *)foursquare {
NSLog(#"authorized!");
}
- (void)foursquareDidNotAuthorize:(BZFoursquare *)foursquare error:(NSDictionary *)errorInfo {
NSLog(#"not authorized! %s: %#", __PRETTY_FUNCTION__, errorInfo);
}
- (IBAction)click:(id)sender {
if (![foursquare_ isSessionValid]){
NSLog(#"here");
[foursquare_ startAuthorization];
} else {
[foursquare_ invalidateSession];
}
}
- (IBAction)checkin:(id)sender {
NSDictionary *parameters = [NSDictionary dictionaryWithObjectsAndKeys:#"4d341a00306160fcf0fc6a88", #"venueId", #"public", #"broadcast", kClientID, #"oauth_token", nil];
self.request = [foursquare_ requestWithPath:#"checkins/add" HTTPMethod:#"POST" parameters:parameters delegate:self];
[request_ start];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
}
#end
can you help me guys? any help will highly be appreciated.
https://developer.foursquare.com/overview/responses
401 (Unauthorized) The OAuth token was provided but was invalid.
Might you have somehow corrupted your oauth token?
I am using the code below & it is working for me :
NSDictionary *parameters = #{#"venueId": #"4a0c6465f964a5202a751fe3", #"broadcast": #"public",#"oauth_token":kClientID};

in app purchase response never comes

In my iPhone app, i've set up an in app purchase. I start the request like this:
SKProductsRequest *request= [[SKProductsRequest alloc] initWithProductIdentifiers: [NSSet setWithObject: #"com.nicknoble.tiprounder.upgrade"]];
request.delegate = self;
[request start];
And I use this method to get the response:
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
NSLog(#"response recieved");
}
And this one to catch an error:
-(void)request:(SKRequest *)request didFailWithError:(NSError *)error
{
NSLog(#"%#",error.description);
}
But neither ever get called. My project has no warnings or errors, and I am running this on my device (iPhone). Any suggestions?
EDIT:
So it works on my window's root view controller, but not on modal view controllers i present. Here is the code from my main view controller:
TestViewController *testView = [[TestViewController alloc] initWithNibName:#"TestViewController" bundle:nil];
[self presentModalViewController:testView animated:YES];
Here is the .h file for TestViewController:
#import <UIKit/UIKit.h>
#import <StoreKit/StoreKit.h>
#interface TestViewController : UIViewController <SKProductsRequestDelegate>
#end
Here is the code for my .m file:
#import "TestViewController.h"
#implementation TestViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
SKProductsRequest *request= [[SKProductsRequest alloc] initWithProductIdentifiers: [NSSet setWithObject: #"com.nicknoble.tiprounder.upgrade"]];
request.delegate = self;
[request start];
}
-(void)request:(SKRequest *)request didFailWithError:(NSError *)error
{
NSLog(#"%#",error.description);
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
NSLog(#"response recieved");
}
#end
Im desperate. Any help would be great! Thanks!
The SKProductsRequest instance need to be retained for the duration of the request. If it's not, it will die silently (without informing its delegate) because nothing else is retaining it.
Right now, ARC will get rid of your SKProductsRequest as soon as the code exits the scope where you allocate it.
A solution would be to keep your SKProductsRequest in an ivar and set it to nil when the request completes/fails. This is also handy to prevent starting a request while there's already one in progress:
// Define _productsRequest as an ivar of type SKProductsRequest in your class
- (void)someMethodThatInitiatesTheProductsRequest
{
if( _productsRequest != nil )
return; // There's already a request in progress. Don't start another one.
SKProductsRequest *request= [[SKProductsRequest alloc] initWithProductIdentifiers: [NSSet setWithObject: #"com.nicknoble.tiprounder.upgrade"]];
request.delegate = self;
[request start];
_productsRequest = request; // <<<--- This will retain the request object
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
NSLog(#"response recieved");
_productsRequest = nil; // <<<--- This will release the request object
}
-(void)request:(SKRequest *)request didFailWithError:(NSError *)error
{
NSLog(#"%#",error.description);
_productsRequest = nil; // <<<--- This will release the request object
}
check your product identifier first.
also check if the class in which these methods are implemented is not released somehow. (might be autoreleased and got released automatically while you are waiting for response)

NSArray with multiple nested requests

I have an app that uses a segmentedControl. First item is an "All" item, where the rest is created from an array based on result from webservice. When "All" is selected I want to request all the request.
How can I go about this,
NSArray *urls = [NSArray arrayWithObjects:#"http://service/group/1/",
#"http://service/group/2/", nil];
I want to collect all result from the calls into a collection and display it in a UITableView when the "All" item is selected and probably in viewDidLoad.
For the other segments only one of the request is issued and callback with an array that then is used in:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
I have tried to look at this example for making the request from the array MultipleDownloads
Thanks,
The method in my viewController to initiate the multiple download:
- (void)requestChildrenInBackground {
queue = [[NSOperationQueue alloc] init];
//Todo remove hard coded and get from previous request respons
NSArray *urls = [NSArray arrayWithObjects: #"http://service/1/children",
#"http://service/2/children",
#"http://service/3/children", nil];
NSLog(#"%#", urls);
for (NSString * url in urls)
{
GetSchedule *operation =
[GetSchedule urlDownloaderWithUrlString:url];
[queue addOperation:operation];
}
}
This is how the multiple request gets handled:
#import "GetSchedule.h"
#import "JSON.h"
#import "Authentication.h"
#import "AttendanceReportViewController.h"
#interface GetSchedule ()
- (void)finish;
#end
#implementation GetSchedule
#synthesize appDelegate;
#synthesize username;
#synthesize password;
#synthesize authenticationString;
#synthesize encodedLoginData;
#synthesize schedulesArray;
#synthesize url = _url;
#synthesize statusCode = _statusCode;
#synthesize data = _data;
#synthesize error = _error;
#synthesize isExecuting = _isExecuting;
#synthesize isFinished = _isFinished;
+ (id)urlDownloaderWithUrlString:(NSString *)urlString {
NSURL * url = [NSURL URLWithString:urlString];
GetSchedule *operation = [[self alloc] initWithUrl:url];
return [operation autorelease];
}
- (id)initWithUrl:(NSURL *)url {
self = [super init];
if (self == nil)
return nil;
_url = [url copy];
_isExecuting = NO;
_isFinished = NO;
return self;
}
- (void)dealloc
{
[username release];
[password release];
[encodedLoginData release];
[_url release];
[_connection release];
[_data release];
[_error release];
[super dealloc];
}
- (BOOL)isConcurrent
{
return YES;
}
- (void)start
{
if (![NSThread isMainThread])
{
[self performSelectorOnMainThread:#selector(start) withObject:nil waitUntilDone:NO];
return;
}
self.username = appDelegate.username;
self.password = appDelegate.password;
Authentication *auth = [[Authentication alloc] init];
authenticationString = (NSMutableString*)[#"" stringByAppendingFormat:#"%#:%#", username, password];
self.encodedLoginData = [auth encodedAuthentication:authenticationString];
[auth release];
NSLog(#"operation for <%#> started.", _url);
[self willChangeValueForKey:#"isExecuting"];
_isExecuting = YES;
[self didChangeValueForKey:#"isExecuting"];
// Setup up the request with the url
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]
initWithURL:_url];
[request setHTTPMethod:#"GET"];
[request setValue:[NSString stringWithFormat:#"Basic %#", encodedLoginData] forHTTPHeaderField:#"Authorization"];
_connection = [[NSURLConnection alloc] initWithRequest:request
delegate:self];
if (_connection == nil)
[self finish];
else {
_data = [[NSMutableData alloc] init];
}
}
- (void)finish
{
NSLog(#"operation for <%#> finished. "
#"status code: %d, error: %#, data size: %u",
_url, _statusCode, _error, [_data length]);
[_connection release];
_connection = nil;
[self willChangeValueForKey:#"isExecuting"];
[self willChangeValueForKey:#"isFinished"];
_isExecuting = NO;
_isFinished = YES;
[self didChangeValueForKey:#"isExecuting"];
[self didChangeValueForKey:#"isFinished"];
}
#pragma mark -
#pragma mark NSURLConnection delegate
- (void)connection:(NSURLConnection *)connection
didReceiveResponse:(NSURLResponse *)response
{
//[_data release];
//_data = [[NSMutableData alloc] init];
[_data setLength:0];
NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse *)response;
_statusCode = [httpResponse statusCode];
}
- (void)connection:(NSURLConnection *)connection
didReceiveData:(NSData *)data
{
[_data appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// Parse the responseData of json objects retrieved from the service
SBJSON *parser = [[SBJSON alloc] init];
NSString *jsonString = [[NSString alloc] initWithData:_data encoding:NSUTF8StringEncoding];
NSDictionary *jsonData = [parser objectWithString:jsonString error:nil];
NSMutableArray *array = [jsonData objectForKey:#"Children"];
schedulesArray = [NSMutableArray array];
[schedulesArray addObject:array];
// Callback to AttendanceReportViewController that the responseData finished loading
[attendanceReportViewController loadSchedule];
[self finish];
}
- (void)connection:(NSURLConnection *)connection
didFailWithError:(NSError *)error
{
_error = [error copy];
[self finish];
}
#end
When all data is received I want to call back to my ViewController and get an array with all data from all request made.
Create a downloader
Create a downloader class using NSURLConnection.
Keep a member variable called downloaderObjectId.
Write a delegate method for this object. This method will pass the downloaded data and downloaderObjectId back to the delegate.
In the delegate.
Create multiple downloader objects(As per your ncessity) with unique value for the downloaderObjectId.
Store these objects in a NSMutableDictionary
Key for each object will be downloaderObjectId. so that when the delegate method is called after download you take the exact object back from the NSMutableDictionary using this key.
Main point.
Each time delegate is called. You should remove the object from dictionary(The object who is done with the download and called his delgate. You can identify this object by the key downloaderObjectId he holds. )
Then check the count of dictionary. If it is zero you can make sure that your downloads are completed. So you can call your viewcontroller.