NSUrlConnection doesnt seem to be working, - ios

I'm trying to use googletts converted and seem to be running into trouble. I think I made the class correctly in terms of structure. But I dont think the NSURLConnection is returning any useful data. Can someone please help me check if its working and if not why?
In the connectiondidfinishloading section I am checking download length
NSLog(#"hmmmm %lu", (unsigned long)[downloadedData length])
which is returning 0. Thats why I think its not working.
The goal is to have the app speak what is downloaded
Thanks!!!
I just have a button in my view controller that launches everything
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#import "RJGoogleTTS.h"
#interface ViewController : UIViewController <CLLocationManagerDelegate>
#property (weak, nonatomic) IBOutlet UILabel *userLabel;
#property (strong, nonatomic) CLLocationManager *locationManager;
#property (strong, nonatomic) CLGeocoder *geoCoder;
#property (strong, nonatomic) RJGoogleTTS *googleTTS;
- (IBAction)geoCodeLocation:(id)sender;
- (IBAction)rjGoogleButton:(id)sender;
#end
here is the implementation file
- (IBAction)rjGoogleButton:(id)sender {
googleTTS = [[RJGoogleTTS alloc]init];
[googleTTS convertTextToSpeech:#"How are you today user?"];
}
RJGoogleTTS.h
#import <Foundation/Foundation.h>
#protocol RJGoogleTTSDelegate <NSObject>
#required
- (void)receivedAudio:(NSMutableData *)data;
- (void)sentAudioRequest;
#end
#interface RJGoogleTTS : NSObject {
id <RJGoogleTTSDelegate> delegate;
NSMutableData *downloadedData;
}
#property (nonatomic, retain) id <RJGoogleTTSDelegate> delegate;
#property (nonatomic, retain) NSMutableData *downloadedData;
- (void)convertTextToSpeech:(NSString *)searchString;
#end
.m
#import "RJGoogleTTS.h"
#import <AVFoundation/AVFoundation.h>
#implementation RJGoogleTTS
#synthesize delegate, downloadedData;
- (id)init
{
self = [super init];
if (self) {
// Initialization code here.
}
return self;
}
- (void)convertTextToSpeech:(NSString *)searchString {
NSString *search = [NSString stringWithFormat:#"http://translate.google.com/translate_tts?q=%#", searchString];
search = [search stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
NSLog(#"Search: %#", search);
self.downloadedData = [[NSMutableData alloc] initWithLength:0];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:search]];
[request setValue:#"Mozilla/5.0" forHTTPHeaderField:#"User-Agent"];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
[delegate sentAudioRequest];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
NSLog(#"did you receive response user");
[self.downloadedData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSLog(#"did you receive data user");
[self.downloadedData appendData:data];
// AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc]initWithData:downloadedData error:nil];
// [audioPlayer play];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(#"Failure");
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSLog(#"it worked user!!!");
[delegate receivedAudio:self.downloadedData];
NSLog(#"hmmmm %d", [self.downloadedData length]);
// NSString *txt = [[NSString alloc] initWithData:downloadedData encoding: NSASCIIStringEncoding];
// NSLog(#"%#hello",txt);
}
#end

Remember that this is happening asynchronously. You set the size of downloadedData to 0 after your call the NSURLConnection.
Move:
self.downloadedData = [[NSMutableData alloc] initWithLength:0];
before your call to NSURLConnection.

There's nothing wrong with your NSURLConnection methods. Your search string is wrong. It should be:
NSString *search = [NSString stringWithFormat:#"http://translate.google.com/translate_tts?tl=en&q=%#",searchString];

You didn't start the URLConnection. Change [[NSURLConnection alloc] initWithRequest:request delegate:self]; like this [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];

Related

Objective c iOS passing data

hi I am new to iOS and below is my code I have to pass the top that I get from request reply...please help me I am stuck here
first view controller is otp view second vc is verifyviewcontroller
Otp view c.h
#import <UIKit/UIKit.h>
#interface OtpViewController : UIViewController
#property (nonatomic, retain) NSString *str;
#end
otpviewcontroller.m
#import "OtpViewController.h"
#import "VerifyViewController.h"
#interface OtpViewController () <VerifyViewControllerDelegate>
#property (weak, nonatomic) IBOutlet UIImageView *bbi;
#property (weak, nonatomic) IBOutlet UIButton *submittf;
#property (weak, nonatomic) IBOutlet UITextField *mobiletf;
#property (weak,nonatomic) NSArray *tmp;
#property(weak,nonatomic) NSString *requestReply ;
//#property(weak,nonatomic) NSDictionary *A;
#end
#implementation OtpViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"background"]];
NSLog(#"viewDidLoad");
[super viewDidLoad];
}
- (IBAction)submitb:(id)sender
{
if (_mobiletf.text && _mobiletf.text.length >0 )
{
/* not empty - do something */
NSString *post = [NSString stringWithFormat:#"phone=%#",_mobiletf.text];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
// Next up, we read the postData's length, so we can pass it along in the request.
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
// Now that we have what we'd like to post, we can create an NSMutableURLRequest, and include our postData.
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:#"http://www.sitesandflats.com/send_otp.php"]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:postData];
NSLog(#"the data Details is %#", post);
// And finally, we can send our request, and read the reply by creating a new NSURLSession:
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
[[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSString *requestReply = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
NSLog(#"requestReply: %#", requestReply);
NSString *str=requestReply;
VerifyViewController *vc = [[VerifyViewController alloc] init];
NSString *tmp=requestReply;
NSLog(#"%#",str);
NSLog(#"%#",_tmp);
}] resume];
[ self performSegueWithIdentifier:#"b1" sender:self];
}
else
{
/* what ever */
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Please check your input!!."
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(nullable id)sender{
VerifyViewController *loadCtr = (VerifyViewController *)segue.destinationViewController;
loadCtr.delegate = self;
loadCtr.tmpStr = (#"otp: %#",_tmp);
NSLog(#"passing val: %#",_tmp);
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
Verify view controller.h
#import <UIKit/UIKit.h>
#protocol VerifyViewControllerDelegate <NSObject>
-(void)moveToA:(NSString *)str;
#end
#interface VerifyViewController : UIViewController
#property (nonatomic, copy) NSString *tmpStr;
#property (nonatomic, assign) id <VerifyViewControllerDelegate> delegate;
//#property (nonatomic, strong) OtpViewController *received;
//#property (strong, nonatomic) IBOutlet UITextField *textDisplay;
#property(nonatomic,weak) NSMutableArray *myAray;
#property(nonatomic,strong) NSString *object;
#property(strong,nonatomic) NSString *tmp1;
#end
Verify view controller.m
#import "VerifyViewController.h"
#import "OtpViewController.h"
#interface VerifyViewController ()
#property (weak, nonatomic) IBOutlet UITextField *otptf;
#property (weak, nonatomic) IBOutlet UIButton *submitb;
//#property (weak,nonatomic) textDisplay;
//#property (weak,nonatomic) NSString *received;
#end
#implementation VerifyViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"background"]];
// Do any additional setup after loading the view.
}
- (IBAction)submitb:(id)sender {
NSLog(#"%#",_tmpStr);
if(_otptf.text==_tmpStr)
{
[self performSegueWithIdentifier:#"b2" sender:self];
}
else{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Incorrect otp please check the input!!!."
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
at nslog I get reply as ("success":"1";"otp":"985123") I need this otp to store and verify in next page please help
First you need to change property
From
#property (weak,nonatomic) NSArray *tmp;
To
#property (strong,nonatomic) NSStirng *tmp;
Assign value to tmp as below
[[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSString *requestReply = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; // this is json string
NSError *error;
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; // you need to convert to dictionary object
NSLog(#"requestReply: %#", jsonDict);
self.tmp=[jsonDict valueForKey:#"otp"] ; // you need to extract value using the key [requestReply valueForKey:#"otp"];
NSLog(#"%#",self.tmp);
}] resume];
Pass tmp to VerifyVIewController
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(nullable id)sender{
VerifyViewController *loadCtr = (VerifyViewController *)segue.destinationViewController;
loadCtr.delegate = self;
loadCtr.tmpStr = self.tmp;
NSLog(#"passing val: %#",_tmp);
}

Custom delegate method doesn't get called

So, I'm following this answer in trying to pass data between two classes in an iOS project without storyboards. I'm trying to abstract all my server calls in a different class, so the ViewControllers don't get too cramped. I have an OfferRequest class, which handles the server requests and declares the protocol:
#protocol OfferRequestDelegate <NSObject>
-(void)addOfferRequest: (OfferRequest *)request dataFromRequest: (NSMutableArray *)data;
#end
#interface OfferRequest : NSObject <LocationManagerDelegate, NSURLConnectionDataDelegate>
#property (nonatomic, weak) id <OfferRequestDelegate> delegate;
#end
The idea is to call addOfferRequest: dataFromRequest in connectionDidFinishLoading, set the data as the result from the request and pass it on to the ViewController.
In OfferRequest.m:
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSMutableArray *result = [NSJSONSerialization JSONObjectWithData:receivedData options:kNilOptions error:nil];
[self.delegate addOfferRequest:self dataFromRequest:result];
}
I declare my ViewController as a delegate for the OfferRequest:
#interface CategorySuggestionViewController : UIViewController <OfferRequestDelegate>
Initialize the OfferRequest object and set it's delegate:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
offer = [OfferRequest new];
offer.delegate = self;
}
And then implement the delegate method:
-(void)addOfferRequest:(OfferRequest *)request dataFromRequest:(NSMutableArray *)data {
NSLog(#"received data = %#", data);
}
But it never gets called. What am I missing ?
try this...
your OfferRequest class like below i have given name it as connectionClass
connectionClass.h
#protocol connectionDelegate <NSObject>
-(void)connectionSucceed:(NSData *)data;
-(void)connectionFailed:(NSError *)error;
#end
#import <Foundation/Foundation.h>
#interface connectionClass : NSObject
{
id<connectionDelegate> delegate;
NSMutableData *receivedData;
NSString *encodedString;
NSMutableURLRequest *theRequest;
NSURL *url;
NSString *length;
NSURLConnection *Connect;
}
#property(nonatomic, retain) id<connectionDelegate> delegate;
#property(nonatomic, retain) NSMutableData *receivedData;
- (void)connectionWithURL:(NSString *)URL;
#end
connectionClass.m
#import "connectionClass.h"
#implementation connectionClass
#synthesize delegate, receivedData;
- (void)connectionWithURL:(NSString *)URL
{
url=[[NSURL alloc] initWithString:[self urlencode:URL]];
theRequest= [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60];
[theRequest setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
length = [NSString stringWithFormat:#"%lu", (unsigned long)[URL length]];
[theRequest setValue:length forHTTPHeaderField:#"Content-Length"];
[theRequest setHTTPMethod:#"POST"];
[theRequest setHTTPBody:[URL dataUsingEncoding:NSUTF8StringEncoding]];
Connect = [NSURLConnection connectionWithRequest:theRequest delegate:self];
if (Connect)
{
self.receivedData = [NSMutableData data];
}
else
{
NSError *error;
[self.delegate connectionFailed:error];
}
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[self.receivedData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[self.receivedData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[self.delegate connectionSucceed:self.receivedData];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
[self.delegate connectionFailed:error];
}
-(NSString *) urlencode: (NSString *) string
{
encodedString = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)string, NULL, (CFStringRef)#"", kCFStringEncodingUTF16));
return encodedString;
}
#end
don't forget to import your connectionclass and delegate
#interface yourclass : UIViewController<connectionDelegate>
Initialize the OfferRequest object and set it's delegate:
-(void)viewWillAppear:(BOOL)animated
{
connection = [[connectionClass alloc]init];
connection.delegate = self;
[connection connectionWithURL:[NSString stringWithFormat:#"pass your url here"]];
}
The delegate method will have your values
-(void)connectionSucceed:(NSData *)data
{
NSError *error;
self.dictionary = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
//nslog your data
}
//Connection failure
-(void)connectionFailed:(NSError *)error
{
//handle error message
}
Ok, I don't know where the problem exactly was, but what I did to fix it, was to create a new init method, where I pass the delegate:
-(instancetype)initWithDelegate: (id<OfferRequestDelegate>) delegate {
self = [super init];
if (self) {
self.delegate = delegate;
}
return self;
}
So I initialize the OfferRequest object in the VC and pass self and now it works.
I guess delegate should be a pointer object and not the object.
It may be help you
#property (nonatomic, weak) NSObject <OfferRequestDelegate> *delegate;
and make should your delegate is been set, i.e. make sure your code below is getting called.
[self.delegate addOfferRequest:self dataFromRequest:result];

iOS NSError/NSDictionary for callbacks

I am developing a framework which requires error callbacks. I have used delegate methods to give error callbacks to the users(developer) of the framework. Can I use NSError to indicate error details in the delegate method or simply use NSDictionary instead ? Are there any memory issues concerned here?
Instead of delegate methods, you should use blocks with proper error handling, something like this:
Interface:
typedef void(^ResultBlock)(id result, NSError *error);
extern NSString * const DummyErrorDomain;
enum{
DummyErrorReason1,
DummyErrorReason2
};
#interface Dummy : NSObject
-(void)doSomething:(ResultBlock)resultBlock;
#end
Implementation with async NSURLConnection:
NSString * const DummyErrorDomain = #"DummyErrorDomain";
#interface Dummy ()
#property (strong) ResultBlock resultBlock;
#property NSURLConnection *connection;
#property NSMutableData *responseData;
#end
#implementation Dummy
-(void)doSomething:(ResultBlock)resultBlock
{
self.resultBlock = resultBlock;
self.responseData = [[NSMutableData alloc] init];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:#"dummyURL"]];
self.connection = [[NSURLConnection alloc]initWithRequest:request delegate:self];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
self.resultBlock(nil,error);
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
self.resultBlock(self.responseData, nil);
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
[self.responseData appendData:data];
}
#end
Usage:
-(void)usage
{
Dummy *dummy = [[Dummy alloc] init];
[dummy doSomething:^(id result, NSError *error) {
if(result){
// everything went fine
}else{
// error handling
}
}];
}

xcode Finding memory leaks with Instruments

I have an iOS project with ARC enabled and i'm using Leaks instrument to find leaks.
i have one leak in this line of code and i don't understand why it's a leak :
[self.activeDownload appendData:data];
this is the code of the class
#interface IconDownloader ()
#property (nonatomic, strong) NSMutableData *activeDownload;
#property (nonatomic, strong) NSURLConnection *imageConnection;
#end
#implementation IconDownloader
#synthesize url = _url;
#synthesize activeDownload = _activeDownload;
#synthesize imageConnection = _imageConnection;
- (void)startDownload
{
self.activeDownload = [NSMutableData data];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:self.url]];
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
self.imageConnection = conn;
}
- (void)cancelDownload
{
[self.imageConnection cancel];
self.imageConnection = nil;
self.activeDownload = nil;
self.completionHandler = nil;
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[self.activeDownload appendData:data]; // leak
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
self.activeDownload = nil;
self.imageConnection = nil;
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
if (self.completionHandler) {
self.completionHandler(self.activeDownload);
}
self.imageConnection = nil;
}

NSInvalidArgumentException in sending POST request to HTTP

I'm writing simple code which is sending me response from http server after sending a POST request to it but if I try moving everything to another file XCode shows me this error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'data parameter is nil'
Here are the two files I'm using to make this work:
#import "HTTPRequestHandler.h"
#interface HTTPRequestHandler ()
#property (strong, nonatomic) NSURL *requestURL;
#property (strong, nonatomic) NSData *httpBody;
#property (strong, nonatomic) NSMutableData *responseData;
#end
#implementation HTTPRequestHandler
- (id)initWithURL:(NSString *)url body:(NSString *)body
{
if (self = [super init]) {
self.requestURL = [[NSURL alloc] initWithString:url];
self.httpBody = [body dataUsingEncoding:NSUTF8StringEncoding];
}
return self;
}
- (void)makeConnectionWithRequest
{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:self.requestURL];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:self.httpBody];
[NSURLConnection connectionWithRequest:request delegate:self];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(#"Dane doszły 1");
[self.responseData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSLog(#"Dane doszły 2");
[self.responseData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(#"Dane doszły 3");
NSDictionary *recievedData = [NSJSONSerialization JSONObjectWithData:self.responseData options:kNilOptions error:nil];
NSLog(#"%#", [recievedData description]);
}
#end
and the second one:
#import "ViewController.h"
#import "HTTPRequestHandler.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
HTTPRequestHandler *request = [[HTTPRequestHandler alloc] initWithURL:#"http://own-dev1.railwaymen.org:4006/api/get_grant_key"
body:#"email=vergun#gmail.com&password=password"];
[request makeConnectionWithRequest];
}
#end
Okey, got it! Just forgot self.responseData = [NSMutableData data];

Resources