UIWebView Not loading - iphone

I am having a problem where UrlDisplay isn't displaying any data. UrlDisplay is located at the bottom of my .M. What I am doing is requesting a website collecting a few urls specific to the users request. Then setting up UiWebViews for them to navigate though is there any way to split a single UiWebView, or is this the best way to do it? (My sample is only collecting one website and trying to set one website to a UIWebView)I am not sure of why this is happening Everything in the .h is connected properly to the storyboard. Thanks for the help in advanced for any feed back!
.H
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (weak, nonatomic) IBOutlet UIWebView *UrlDisplay;
#end
.M
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize UrlDisplay;
- (void)viewDidLoad
{
[super viewDidLoad];
NSURL *website = [NSURL URLWithString:#"www.Google.com"];
NSURLRequest *request = [NSURLRequest requestWithURL:website];
NSURLResponse* response = nil;
NSError *error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
//storing data in a string
NSString *myString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSArray *newString = [myString componentsSeparatedByString:#"\n"];
// Do any additional setup after loading the view, typically from a nib.
NSMutableString *curLineNum;
NSString *curLine;
NSMutableArray *URL =[[NSMutableArray alloc]init];
int i;
for (i = 0; i <[newString count]; i++) {
curLine = [newString objectAtIndex:i];
if ([curLine rangeOfString:#"Start Here"].location != NSNotFound) {
NSScanner *scanner = [NSScanner scannerWithString:curLine];
[scanner scanUpToString:#"Start Here" intoString:NULL];
[scanner setScanLocation:([scanner scanLocation]) + 16];
[scanner scanUpToString:#"End Here" intoString:&curLineNum];
[Url addObject:curLineNum];
}
}
NSURL *preWebsite = [NSURL URLWithString:[Url objectAtIndex:0]];
NSURLRequest *preRequest = [NSURLRequest requestWithURL:preWebsite];
[UrlDisplay loadRequest:preRequest];
//NSLog(#"%#",myString);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end

the method URLWithString always expecting full URL path including URL scheme. In your case URL scheme is missing. Try this.
NSURL *website = [NSURL URLWithString:#"http://www.Google.com"];

Related

App is crashing with EXC_BAD_ACCESS on background

i setted NSString *oldChat in the header file like this:
#interface CTFChatViewController : UIViewController {
NSString *oldChat;
}
- (void)updateChat;
#property (nonatomic, retain) NSString *oldChat;
#end
and then i used it:
- (void)updateChat
{
NSString *chat = [NSString stringWithContentsOfURL:[NSURL URLWithString:#"http://theshay.byethost7.com/chat.php"] encoding:NSUTF8StringEncoding error:nil];
if (![chat isEqual:oldChat])
{
[webView loadHTMLString:chat baseURL:nil];
oldChat = chat;
}
[self performSelectorInBackground:#selector(updateChat) withObject:nil];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
NSString *chat = [NSString stringWithContentsOfURL:[NSURL URLWithString:#"http://theshay.byethost7.com/chat.php"] encoding:NSUTF8StringEncoding error:nil];
oldChat = chat;
[webView loadHTMLString:chat baseURL:nil];
[self performSelectorInBackground:#selector(updateChat) withObject:nil];
}
App crashed on if (![chat isEqual:oldChat]) with EXC_BAD_ACCESS error.
why it crashed ?
(XCode 4.5.2, iPhone Simulator 6.0, Base SDK 6.0)
oldChat is autorelease object. Retain it and use isEqualToString for string comparison.
NSString *chat = [NSString stringWithContentsOfURL:[NSURL URLWithString:#"http://theshay.byethost7.com/chat.php"] encoding:NSUTF8StringEncoding error:nil];
oldChat = chat;
[oldChat retain];
You have to check your NSString is equal or not using isEqualToString: method. Your code should be like this
if (![chat isEqualToString:oldChat]){
//Do something
}

NSURLConnection and JSON Data

I am stuck with something crazy. I used ASIHTTPRequest to receive my data from a web service and everything worked fine. I switched to using a NSURLConnection and I am receiving the same data and parsing it the same way but my code won't recognize the data with the NSURLConnection.
Here is the data I am receiving (from NSLog)
Did receive data: {"d":"[{\"id\":1.0,\"Category\":1,\"hPlan\":0.0,\"Tip\":\"It takes 3500
calories to gain a pound. If you want to lose a pound per week, reduce your calorie
intake by 250 calories and incorporate daily physical activity that will burn 250
calories.\",\"TipDate\":\"2012-05-12T00:00:00\",\"TimeStamp\":\"AAAAAAAAB9I=\"}]"}
2012-06-06 09:42:11.809 StaticTable[27488:f803] Jsson Array: 0
2012-06-06 09:42:11.809 StaticTable[27488:f803] Jsson Array: (null)
Code:
#import "UYLFirstViewController.h"
#import "MBProgressHUD.h"
#import "JSON.h"
#interface UYLFirstViewController ()
#end
#implementation UYLFirstViewController
#pragma mark -
#pragma mark === UIViewController ===
#pragma mark -
#synthesize MessageField;
#synthesize jsonArray = _jsonArray;
#synthesize TipLabelField;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.title = NSLocalizedString(#"Tickle!", #"Tickle!");
self.tabBarItem.image = [UIImage imageNamed:#"heart_plus"];
[self GetTipOfDay];
}
return self;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
-(BOOL)GetTipOfDay{
NSDate *date = [NSDate date];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc]init];
[dateFormat setDateFormat:#"EEEE MMMM d, YYYY"];
NSString *dateString = [dateFormat stringFromDate:date];
NSString *yourOriginalString = #"Tip of the Day for ";
yourOriginalString = [yourOriginalString stringByAppendingString:dateString];
TipLabelField.text = yourOriginalString;
NSURL *url = [NSURL URLWithString:#"http://www.mysite.com/api/GetHealth.asmx/getTipOfDay"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setHTTPMethod:#"GET"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[NSURLConnection connectionWithRequest:request delegate:self];
// Clear text field
MessageField.text = #"";
// Start hud
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.labelText = #"Gathering Tip of the Day...";
return TRUE;
}
- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[MBProgressHUD hideHUDForView:self.view animated:YES];
NSLog(#"Did receive data: %#", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
NSDictionary *responseDict = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] JSONValue];
NSString *jsonResponse = [responseDict objectForKey:#"d"];
self.jsonArray = [jsonResponse JSONValue];
NSLog(#"Jsson Array: %d", [jsonArray count]);
NSLog(#"Jsson Array: %#", jsonArray);
NSEnumerator *myEnumerator;
myEnumerator = [jsonArray objectEnumerator];
int i;
i=0;
id myObject;
while (myObject = [myEnumerator nextObject])
{
NSDictionary *itemAtIndex = (NSDictionary *)[self.jsonArray objectAtIndex:i];
NSLog(#"Checking for games");
NSString *myCheck = [itemAtIndex objectForKey:#"FName"];
if ([myCheck length] != 0)
{
// NSLog(myCheck);
MessageField.text = myCheck;
}
}
}
- (void)viewDidUnload {
[self setMessageField:nil];
[self setTipLabelField:nil];
[super viewDidUnload];
}
#end
#import <UIKit/UIKit.h>
#interface UYLFirstViewController : UIViewController{
NSMutableArray *jsonArray;
}
#property (weak, nonatomic) IBOutlet UILabel *MessageField;
#property (weak, nonatomic) NSMutableArray *jsonArray;
#property (weak, nonatomic) IBOutlet UILabel *TipLabelField;
-(BOOL)GetTipOfDay;
#end
-didRecieveData can be called multiple times as the bytes and chunks come in. You should move your logic to -connectionDidFinishLoading. This will let you know when the connection is completely done and the data is ready to be parsed.
You're only implementing one of the NSURLConnectionDelegate methods. Try adding this
- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
//set up *receivedMutableString as instance variable in .h
if (!receivedMutableString) {
self.receivedMutableString = [[NSMutableString alloc] initWithData:data encoding:NSUTF8StringEncoding];
} else {
NSString *dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
[receivedMutableString appendString:dataString];
}
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
//Now receivedMutableString contains all json data
...continue with your code
}
NSURLConnection is a bit of overkill if you're just doing a simple GET request (and you're developing for an iOS version that supports blocks). You can do this in a dispatch_async block:
- (void) getData
{
dispatch_async(<some_queue>, ^{
NSError * error = nil;
NSString * response = [NSString stringWithContentsOfURL: stringWithContentsOfURL: requestUrl error: &error];
// process JSON
dispatch_async(dispatch_get_main_queue(), ^{
// Update UI on main thread
}
});
}
As you can see from my example code, you can also perform your JSON processing on the background queue (provided the method you're calling is thread safe). Just pass back to the main queue to update the UI.
Seems like the issue had nothing to do with fetching from the webservice. I had to define my array as __strong. Thanks for all the help. I did get some good ideas on how to do things better.

iOS - Why my NSURL isn't retained in the init method?

I'm creating a new UIViewController with 2 properties :
#property (retain, nonatomic) NSURL *url;
#property (retain, nonatomic) NSString *title;
and synthetised :
#synthesize url = _url;
#synthesize title = _title;
in my custom init method i'm not using the setter like the Memory Management Guide says but when I need to use the properties in the viewDidLoad, the url seems empty, the title doesn't
- (id)initWithURL:(NSURL *)url andTitle:(NSString *)titleTemp
{
self = [super initWithNibName:#"navigatorViewController" bundle:nil];
if (self) {
_url = url;
_title = titleTemp;
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
[_titreBarButtonItem setTitle:_title];
NSURLRequest *urlRequest = [[NSURLRequest alloc] initWithURL:_url];
[_webView loadRequest:urlRequest];
[urlRequest release];
}
I can see my title but my web view is blank.
If I use self.url in the init, it's working !
Do you have an idea ?
PS : Here's how I call my init :
NSString *urlString = [[[NSBundle mainBundle] pathForResource:#"infos" ofType:#"html"] copy];
NSURL *url = [[NSURL alloc] initFileURLWithPath:urlString];
[urlString release];
navigatorViewController *navigatorVC = [[navigatorViewController alloc] initWithURL:url andTitle:#"Infos"];
[url release];
[self presentViewController:navigatorVC animated:YES completion:nil];
[navigatorVC release];
Thanks a lot
you are setting up the properties as retain, but this only applies if you use the synthesized getters. By setting the value directly on the ivar, you are bypassing this and the value is not being retained
you should be doing (probably not a great way when you already have setters):
_url = [url retain];
or better:
self.url = url;
or even better as matt said in the comments: use ARC
You must retain the URL either using :
self.url = url;
in the init method or call the retain after assigning the url in the init method like this.
_url = url;
[_url retain];
You need to add a reference (for what you hold) using copy or retain:
_url = [url copy];
_title = [titleTemp copy];
or
_url = [url retain];
_title = [titleTemp retain];
Well if you write a custom init method you need to do the retain your self:
- (id)initWithURL:(NSURL *)url andTitle:(NSString *)titleTemp
{
self = [super initWithNibName:#"navigatorViewController" bundle:nil];
if (self) {
_url = [url retain];
_title = [titleTemp retain];
}
return self;
}
That it worked with title is just that the variable is probably released later then the NSURL passes in the init method.

Links inside Pdf on Webview are not opening in a browser in iPhone

I have parsed urls of pdfs and showing pdf on a webView, but my Links inside webviews are not opening in a browser.i have not used CGPDFDocument. my code is simple :). can anyone help me out.i have seen many similar questions but all are using Quartz.
code :-
#class AppDelegate_iPhone;
#interface PdfShowViewController : UIViewController<UIWebViewDelegate> {
IBOutlet UIWebView *pdfWebview;
AppDelegate_iPhone *appDelegate;
NSMutableData *receivedData;
IBOutlet UIActivityIndicatorView *myIndicator;
IBOutlet UIProgressView *progress;
NSURLRequest* DownloadRequest;
NSURLConnection* DownloadConnection;
long long bytesReceived;
long long expectedBytes;
IBOutlet UILabel *downloadLabel;
}
#property (nonatomic,retain) IBOutlet UILabel *downloadLabel;
#property (nonatomic,retain) IBOutlet UIWebView *pdfWebview;
#property (nonatomic,retain) IBOutlet UIActivityIndicatorView *myIndicator;
#property (nonatomic,retain) IBOutlet UIProgressView *progress;
#property (nonatomic,retain) NSMutableData *receivedData;
#property (nonatomic, readonly, retain) NSURLRequest* DownloadRequest;
#property (nonatomic, readonly, retain) NSURLConnection* DownloadConnection;
#property (nonatomic, retain, readwrite) NSURL *openURL;
-(IBAction)onTapBack;
#end
#implementation PdfShowViewController
#synthesize pdfWebview,myIndicator,progress,receivedData,DownloadRequest,DownloadConnection,downloadLabel,openURL;
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[receivedData appendData:data];
unsigned char byteBuffer[[receivedData length]];
[receivedData getBytes:byteBuffer];
NSLog(#"Data === %ld",receivedData);
NSInteger receivedLen = [data length];
bytesReceived = (bytesReceived + receivedLen);
NSLog(#"received Bytes == %f",bytesReceived);
if(expectedBytes != NSURLResponseUnknownLength)
{
NSLog(#"Expected Bytes in if == %f",expectedBytes);
NSLog(#"received Bytes in if == %f",bytesReceived);
float value = ((float) (bytesReceived *100/expectedBytes))/100;
NSLog(#"Value == %f",value);
progress.progress=value;
}
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[connection release];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
expectedBytes = [response expectedContentLength];
NSLog(#"%f",expectedBytes);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[myIndicator stopAnimating];
[myIndicator removeFromSuperview];
[progress setHidden:YES];
[downloadLabel setHidden:YES];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *pdfPath = [documentsDirectory stringByAppendingPathComponent:#"iPhonePdf.pdf"];
unsigned char byteBuffer[[receivedData length]];
[receivedData getBytes:byteBuffer];
[self.receivedData writeToFile:pdfPath atomically:YES];
[DownloadConnection release];
//Now create Request for the file that was saved in your documents folder
NSURL *url = [NSURL fileURLWithPath:pdfPath];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[pdfWebview setScalesPageToFit:YES];
[pdfWebview loadRequest:requestObj];
}
-(BOOL)webView:(UIWebView *)webView1 shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSURL *requestURL = [request URL];
if(navigationType==UIWebViewNavigationTypeLinkClicked)
{
[[UIApplication sharedApplication] openURL:requestURL];
return NO;
}
else
{
return YES;
}
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
pdfWebview.delegate = self;
appDelegate = (AppDelegate_iPhone *)[[UIApplication sharedApplication] delegate];
[downloadLabel setText:#"Downloading..."];
[downloadLabel setHidden:NO];
[myIndicator setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleWhiteLarge];
myIndicator.hidesWhenStopped = YES;
[myIndicator startAnimating];
// NSString *urlString = [appDelegate.currentBookPressed stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSString *urlString = [appDelegate.currentBookPressed stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
// NSLog(#"The Url Stirng=======%#",urlString);
NSURL *targetURL = [NSURL URLWithString:urlString];
//NSLog(#"Trageted String ------======++++++++%#",targetURL);
DownloadRequest = [NSURLRequest requestWithURL:targetURL cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:1200.0];
DownloadConnection = [[NSURLConnection alloc] initWithRequest:DownloadRequest delegate:self];
if (DownloadConnection) {
receivedData = [[NSMutableData data]retain];
}
[pdfWebview setScalesPageToFit:YES];
[pdfWebview loadRequest:DownloadRequest];
}
-(IBAction)onTapBack
{
[self dismissModalViewControllerAnimated:YES];
}
#end
here is the link which i am trying to open but not opening :-
No, links inside pdf files loaded in a UIWebView won't open when you tap them by default.
You can go the hard way and parse the links out using Quartz as is shown in this other post I answered.
Or, instead of loading a pdf, can you convert the content you are loading to an html file instead? That would be easier, and the links should work then.
You have to use below delegate method
-(BOOL)webView:(UIWebView *)webView1 shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSURL *requestURL = [request URL] ;
if(navigationType==UIWebViewNavigationTypeLinkClicked)
{
[[UIApplication sharedApplication] openURL:requestURL];
return NO;
}
else
{
return YES;
}
}

Trouble using a custom NSObject class to simplify repetitive code in iPhone app

I am trying to store a REST connection model in a single object so that I don't keep having to use it over and over again. Here is the model I created:
//RestModel.h
#import "ASIHTTPRequest.h"
#interface RestModel : NSObject{
NSString* _baseUrl;
NSString* _modelUrl;
}
#property (nonatomic, retain) NSString* modelUrl;
- (id)initWithModel:(NSString*)model;
- (NSDictionary*)getById:(NSInteger*)ident;
- (NSDictionary*)getAll;
#end
//RestModel.m
#import "RestModel.h"
#implementation RestModel
#synthesize modelUrl = _modelUrl;
- (id)init
{
self = [super init];
if (self) {
_baseUrl = #"http://myRESTurl.com";
}
return self;
}
- (id)initWithModel:(NSString*)model
{
self = [super init];
if (self) {
_baseUrl = #"http://myRESTurl.com";
self.modelUrl = [NSString stringWithFormat:#"%#/%#/", _baseUrl, model];
}
return self;
}
- (NSDictionary*)HTTPRequest:(NSURL*)url
{
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request startSynchronous];
NSError *error = [request error];
if(!error){
NSData *responseData = [request responseData];
NSString *errorDesc = nil;
NSPropertyListFormat format;
[error release];
[request release];
return (NSDictionary*)[NSPropertyListSerialization propertyListFromData:responseData mutabilityOption:NSPropertyListMutableContainersAndLeaves format:&format errorDescription:&errorDesc];
}else{
NSLog(#"%#", error);
return nil;
}
}
- (NSDictionary*)getById:(NSInteger*)ident
{
NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:#"%#/%#", self.modelUrl, ident]];
return [self HTTPRequest:url];
}
- (NSDictionary*)getAll
{
NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:#"%#", self.modelUrl]];
return [self HTTPRequest:url];
}
- (void)dealloc
{
[_modelUrl release];
// [_responseData release];
// [_responseDict release];
[super dealloc];
}
#end
Edit: Now it isn't crashing, but my local NSDictionary has a count of 0. I'm calling the following in -viewDidLoad in my controller:
RestModel* rm = [[RestModel alloc] initWithModel:#"user"];
self.dict = [rm getAll];
[rm release];
I planted NSLog of [self.dict count] throughout the controller. It is always 0. The RestModel rm is called, the functions are called (again more NSLogs), but no data. Any ideas?
[error release];
[request release];
Those should be auto-released objects, as you got them by convenience methods, so releasing them explicitly will make your application crash.
NSInteger isn't an object so it isn't necessary to pass it using NSInteger * and certainly you do not want to use the %# format specifier. Instead try this:
- (NSDictionary*)getById:(NSInteger)ident
{
NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:#"%#/%d", self.modelUrl, ident]];
return [self HTTPRequest:url];
}