I'm generating an HTML file for an app, and in this HTML file there's a link to a stylesheet and one to an image.
Here's what I tried so far:
NSMutableString *toReturn = [NSMutableString stringWithCapacity:100];
NSString *cssPath = [[NSBundle mainBundle] pathForResource:#"etapes.css" ofType:nil];
[toReturn appendFormat:#"<html><head><title></title><link href=\"%#\" media=\"all\" rel=\"stylesheet\" type=\"text/css\" /></head><body>", cssPath];
It generates the right full path to the right file, this is okay if I want to access it on my mac, but on the simulator or my iPhone it doesn't point to the right place at all...
Do you have any idea of how could I make this?
Thanks
I found this tutorial a while back. I ended up just using a <style> tag in the end though.
NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:path];
[webView loadHTMLString:htmlString baseURL:baseURL];
Another way of doing this is like so:
-(NSString *)urlForFileNamed:(NSString *) name ofType:(NSString *) type {
NSString *filePath = [[NSBundle mainBundle] pathForResource: name ofType: type];
if (!filePath) { NSLog(#"No path found for file %#.%#", name, type); }
return filePath;
}
-(void)viewDidLoad {
[super viewDidLoad];
NSString *path = [[NSBundle mainBundle] bundlePath];
baseUrl = [NSURL fileURLWithPath: path];
[view loadHTMLString: [self html] baseURL: [NSURL fileURLWithPath: path]];
}
-(NSString *)html {
// Obviously the below's just a stub for proper HTML
return [NSString stringWithFormat: #"<img src=\"#\" />", [self urlForFileNamed: #"foo" ofType: #"png"]];
}
You may try to edit the line
NSString *cssPath = [[NSBundle mainBundle] pathForResource:#"etapes.css" ofType:nil];
to
NSString *cssPath = [[NSBundle mainBundle] pathForResource:#"etapes" ofType:#"css"];
Related
I'm working on an iOS app for my school that will allow the user to access school documents like schedules, calendars, and grade/tuition sites. I've been doing research on how to save credentials for some of the sites that require logins, and my ultimate goal is not only save credentials, but automatically log in the user to the websites when the webview is loaded as well. So far my code looks like this:
#import "PJP Webview.h"
#implementation PJP_Webview
#synthesize webView, loginView, username, password, body, urlToLink,usernameField,passwordField, firstTime, loginNeeded, callerCell;
-(void) viewDidLoad {
[super viewDidLoad];
loginView.hidden = true;
if (firstTime && loginNeeded) {
loginView.hidden = false;
[self.view bringSubviewToFront:loginView];
}
else {
loginView.hidden = true;
[self.view addSubview:self.webView];
[self.view bringSubviewToFront:webView];
if (loginNeeded) {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSString *usernameSave = [NSString stringWithFormat:#"%#username", self.callerCell];
self.username = [userDefaults objectForKey:usernameSave];
NSString *passwordSave = [NSString stringWithFormat:#"%#password", self.callerCell];
self.password = [userDefaults objectForKey:passwordSave];
NSURL *url = [NSURL URLWithString: urlToLink];
NSString *bodyForUse = [NSString stringWithFormat: body, username, password];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL: url];
[request setHTTPMethod: #"POST"];
[request setHTTPBody: [bodyForUse dataUsingEncoding: NSUTF8StringEncoding]];
[webView loadRequest: request];
}
else {
NSURL *url = [NSURL URLWithString: urlToLink];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webView loadRequest:request];
}
}
}
- (IBAction)acceptInput:(id)sender {
self.username = usernameField.text;
self.password = passwordField.text;
loginView.hidden = true;
[self.view addSubview:self.webView];
[self.view bringSubviewToFront:webView];
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSString *usernameSave = [NSString stringWithFormat:#"%#username", self.callerCell];
[userDefaults setObject:username forKey:usernameSave];
NSString *passwordSave = [NSString stringWithFormat:#"%#password", self.callerCell];
[userDefaults setObject:password forKey:passwordSave];
[userDefaults synchronize];
NSURL *url = [NSURL URLWithString: urlToLink];
NSString *bodyForUse = [NSString stringWithFormat: body, username, password];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL: url];
[request setHTTPMethod: #"POST"];
[request setHTTPBody: [bodyForUse dataUsingEncoding: NSUTF8StringEncoding]];
[webView loadRequest: request];
}
#end
I modeled some of my code after another stack overflow article found here Loading a webpage through UIWebView with POST parameters
An example of one of the websites I am trying to integrate is https://adphila.gradeconnect.com/front/slogin.php
So far my code has not been successful at logging me into the website and taking me to the next page, so I'm not sure if maybe the body I am using for the parameters is wrong, if my code is faulty, or some other issue is present. Also, if you have any suggestions for how to make my previous code more efficient I welcome that too!
Edit: The school also uses gmail for student emails, so is it possible to embed a uiwebview of email content as well? I know Google has their own APIs but I have never used non-Apple libraries before.
Edit 2:
#import "PJP Webview.h"
#implementation PJP_Webview
#synthesize webViewCurrent, loginView, username, password, bodyUsername, bodyPassword, urlToLink,usernameField,passwordField, firstTime, loginNeeded, callerCell, bodyButton;
-(void) viewDidLoad {
[super viewDidLoad];
[webViewCurrent setDelegate:self];
loginView.hidden = true;
if (firstTime && loginNeeded) {
loginView.hidden = false;
[self.view bringSubviewToFront:loginView];
}
else {
loginView.hidden = true;
if (loginNeeded) {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSString *usernameSave = [NSString stringWithFormat:#"%#username", self.callerCell];
self.username = [userDefaults objectForKey:usernameSave];
NSString *passwordSave = [NSString stringWithFormat:#"%#password", self.callerCell];
self.password = [userDefaults objectForKey:passwordSave];
NSURL *url = [NSURL URLWithString: urlToLink];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webViewCurrent loadRequest:request];
}
else {
NSURL *url = [NSURL URLWithString: urlToLink];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webViewCurrent loadRequest:request];
}
[self.view addSubview:self.webViewCurrent];
[self.view bringSubviewToFront:webViewCurrent];
}
}
- (IBAction)acceptInput:(id)sender {
self.username = usernameField.text;
self.password = passwordField.text;
loginView.hidden = true;
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSString *usernameSave = [NSString stringWithFormat:#"%#username", self.callerCell];
[userDefaults setObject:username forKey:usernameSave];
NSString *passwordSave = [NSString stringWithFormat:#"%#password", self.callerCell];
[userDefaults setObject:password forKey:passwordSave];
[userDefaults synchronize];
NSURL *url = [NSURL URLWithString: urlToLink];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webViewCurrent loadRequest:request];
[self.view addSubview:self.webViewCurrent];
[self.view bringSubviewToFront:webViewCurrent];
}
-(void) webViewDidFinishLoad:(UIWebView *)webView {
NSString *fillData = [NSString stringWithFormat:#"document.getElementById('%#').value = '%#';document.getElementById('%#').value = '%#';", bodyUsername, username, bodyPassword, password];
[webView stringByEvaluatingJavaScriptFromString:fillData];
NSString *buttonData = [NSString stringWithFormat:#"document.getElementById('%#').click()", bodyButton];
[webView stringByEvaluatingJavaScriptFromString:buttonData];
}
#end
There is a new error though, void SendDelegateMessage(NSInvocation *): delegate (webView:didFinishLoadForFrame:) failed to return after waiting 10 seconds. main run loop mode: kCFRunLoopDefaultMode
For the website I am using, the bodyUsername is lusername, the bodyPassword lpassword, and the bodyButton login. The page loads but is not executing the javascript.
You can do this by Autopopulating the username and password field of that webpage. First get the name of the username and password field from the webpage. right click on the webpage.
Click on inspect element and then You van easily find it.
Then write the WebView Delegate Method.
// ViewController.m
// WebDemo
//
// Created by Nilesh on 7/31/16.
// Copyright © 2016 Nilesh. All rights reserved.
//
#import "ViewController.h"
#interface ViewController ()<UIWebViewDelegate>
#property (weak, nonatomic) IBOutlet UIWebView *webView;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSString *urlToLink = #"https://adphila.gradeconnect.com/front/slogin.php";
NSURL *url = [NSURL URLWithString: urlToLink];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[_webView loadRequest:request];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void) webViewDidFinishLoad:(UIWebView *)webView {
NSString* userId = #"userName" ;//Your userName
NSString* password = #"password";// Your Password
NSString* jScriptString1 = [NSString stringWithFormat:#"document.forms[0]['lusername'].value='%#'", userId];
NSString* jScriptString2 = [NSString stringWithFormat:#"document.forms[0]['lpassword'].value='%#'", password];
[webView stringByEvaluatingJavaScriptFromString:jScriptString1];
[webView stringByEvaluatingJavaScriptFromString:jScriptString2];
NSString *jsStat = #"document.forms[0]['login'].click()";
[webView stringByEvaluatingJavaScriptFromString:jsStat];
}
#end
JSON web file is not overwriting and replacing the local JSON file on the App.
-(void)writeJsonToFile
{
NSURL *fileJSON = [[NSBundle mainBundle] URLForResource:#"data" withExtension:#"json"];
NSString *filePath = [NSString stringWithFormat:#"%#",fileJSON];
NSString *stringURL = #"website.com/data.json";
NSURL *url = [NSURL URLWithString:stringURL];
NSData *urlData = [NSData dataWithContentsOfURL:url];
[urlData writeToFile:filePath atomically:YES];
}
The destination for urlData and filePath files match each other.
Been looking around the site and other places online, made sure the file path matched.
We can never change the NSBundle file but
you can save in to local then try this
-(void)writeJsonToFile
{
NSString * filePath=[NSString stringWithFormat:#"%#/Documents/data.json",NSHomeDirectory()];
NSString *stringURL = #"website.com/data.json";
NSURL *url = [NSURL URLWithString:stringURL];
NSData *urlData = [NSData dataWithContentsOfURL:url];
[urlData writeToFile:filePath atomically:YES];
}
This code replacing local JSON file when call.
Your JSON file save in your application directory/Documents/ and file name is data.json
website.com/data.json do not return json data, please check it and if needed to change your URL.
I need to download the html file from server url and replace to local html file. I'm using AFNetworking to download the file and store to Documents folder. It's downloading video & audio files. But when i try to download the html files i'm getting below error Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (JSON text did not start with array or object and option to allow fragments not set.) UserInfo=0x83d0730 {NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:#"solarhtml"];
if ([[NSFileManager defaultManager] fileExistsAtPath:dataPath])
[[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:&error];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager.requestSerializer setValue:#"application/x-www-form-urlencoded"
forHTTPHeaderField:#"Content-Type"];
[manager setResponseSerializer:[AFJSONResponseSerializer serializer]];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:#"text/html", nil];
[manager GET:#"http://server.net/projects/index.html"
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) {
[operation.responseData writeToFile:[dataPath stringByAppendingPathComponent:#"index.html"] atomically:YES];
NSLog(#"Successfully downloaded file to %#", [NSURL fileURLWithPath:dataPath]);
NSLog(#"THE RESPONSE: %#", responseObject);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error1) {
NSLog(#"%#", error1);
}];
Access html file:
-(void)estimatesavings:(id)sender{
if(updateclick==YES){
web_estimate=[[UIWebView alloc]initWithFrame:CGRectMake(0, 0, 1024, 768)];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"index.html"];
NSURL *targetURL = [NSURL fileURLWithPath:filePath];
NSURLRequest *request = [NSURLRequest requestWithURL:targetURL];
[web_estimate loadRequest:request];
web_estimate.delegate=self;
[self.view addSubview:web_estimate];
}else{
NSString *pathToBundle = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:pathToBundle];
NSString *htmlFile = [[NSBundle mainBundle] pathForResource:#"index" ofType:#"html"];
NSString *htmlString = [NSString stringWithContentsOfFile:htmlFile encoding:NSUTF8StringEncoding error:nil];
//CGRect fullScreenRect=[[UIScreen mainScreen]applicationFrame];
web_estimate=[[UIWebView alloc]initWithFrame:CGRectMake(0, 0, 1024, 768)];
[web_estimate loadHTMLString:htmlString baseURL:baseURL];
web_estimate.delegate=self;
[self.view addSubview:web_estimate];
}
}
ERROR:
copy failed: Error Domain=NSCocoaErrorDomain Code=4 "The operation couldn’t be completed. (Cocoa error 4.)" UserInfo=0x83c8b50 {NSSourceFilePathErrorKey=/Users/ranganathagv/Library/Application Support/iPhone Simulator/6.1/Applications/CEDFEBEB-2A5C-40A9-8965-761689FD83C2/ActewAGL.app/index.html, NSUserStringVariant=(
Copy
), NSFilePath=/Users/ranganathagv/Library/Application Support/iPhone Simulator/6.1/Applications/CEDFEBEB-2A5C-40A9-8965-761689FD83C2/ActewAGL.app/index.html, NSDestinationFilePath=/Users/ranganathagv/Library/Application Support/iPhone Simulator/6.1/Applications/CEDFEBEB-2A5C-40A9-8965-761689FD83C2/Documents/solarhtml/index.html, NSUnderlyingError=0x83c89c0 "The operation couldn’t be completed. No such file or directory"}c
There were two problems:
The attempt to use AFJSONResponseSerializer and changing the acceptableContentTypes will not work, because the AFJSONResponseSerializer will accept the response, but will still try to parse the JSON. Instead, you should just use AFHTTPResponseSerializer instead. See https://stackoverflow.com/a/21621530/1271826 for more information.
The other problem rests in your open routine. Rather than just opening the file from the bundle, you should open the file in the Documents folder. You might even want to copy the file from the bundle to the Documents folder (in case it hasn't been downloaded yet).
For example:
NSString *documentsFolder = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *solarFolder = [documentsFolder stringByAppendingPathComponent:#"solarhtml"];
NSString *documentsPath = [solarFolder stringByAppendingPathComponent:#"index.html"];
NSString *bundlePath = [[NSBundle mainBundle] pathForResource:#"index" ofType:#"html"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:documentsPath]) {
NSError *error;
if (![fileManager fileExistsAtPath:solarFolder]) {
if (![fileManager createDirectoryAtPath:solarFolder withIntermediateDirectories:YES attributes:nil error:&error]) {
NSLog(#"create folder failed: %#", error);
}
}
if (![fileManager copyItemAtPath:bundlePath toPath:documentsPath error:&error]) {
NSLog(#"copy failed: %#", error);
}
}
NSString *htmlString = [NSString stringWithContentsOfFile:documentsPath encoding:NSUTF8StringEncoding error:nil];
web_estimate=[[UIWebView alloc]initWithFrame:CGRectMake(0, 0, 1024, 768)];
[web_estimate loadHTMLString:htmlString baseURL:baseURL];
This way, if the file hasn't been downloaded at all, this will copy the file from the bundle before trying to open it, if necessary.
I'm trying to display a local html file from a three20 table controller. The table shows up correctly, but when I select the item, all I get is a blank screen. If I use an external URL, the page shows correctly. I haven't tried using UIWebView, but I was wondering if there was an easy way using the Three20 framework.
Thanks.
EDIT: I forgot that has changed recently...
Assuming you have registered a TTWebController in your navigator that way :
TTNavigator* navigator = [TTNavigator navigator];
TTURLMap* map = navigator.URLMap;
[map from:#"*" toViewController:[TTWebController class]];
You can simply open a local html file that way :
NSString *creditsPath = [[NSBundle mainBundle] pathForResource:#"credits" ofType:#"html"];
NSURL *url = [NSURL fileURLWithPath:creditsPath];
TTOpenURL([url description]);
Then all you have to to is to add TTTableLinkedItem or subclass (almost all of TT*Cell are) to your dataSource with a local file URL like that :
NSString *creditsPath = [[NSBundle mainBundle] pathForResource:#"credits" ofType:#"html"];
NSURL *url = [NSURL fileURLWithPath:creditsPath];
TTTableTextItem *item = [TTTableTextItem itemWithText:#"foobar" URL:[url description]];
Much simpler that what I wrote before...
ENDOFEDIT
Forget whats under, unless you're interested in others solutions... (more complex... or not, see last one)
Basically here is how you load content in a UIWebView :
NSString *creditsPath = [[NSBundle mainBundle] pathForResource:#"credits" ofType:#"html"];
NSURL *url = [NSURL fileURLWithPath:creditsPath];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
[webView loadRequest:urlRequest];
The three20 TTWebController can take a request in a query :
- (id)initWithNavigatorURL:(NSURL*)URL query:(NSDictionary*)query {
if (self = [self initWithNibName:nil bundle:nil]) {
NSURLRequest* request = [query objectForKey:#"request"];
if (nil != request) {
[self openRequest:request];
} else {
[self openURL:URL];
}
}
return self;
}
So to open a local html file in a TTWebController you could do this :
NSString *creditsPath = [[NSBundle mainBundle] pathForResource:#"credits" ofType:#"html"];
NSURL *url = [NSURL fileURLWithPath:creditsPath];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
[[TTNavigator navigator] openURLAction:
[[[TTURLAction actionWithURLPath:#"url://to/your/ttwebcontroller"]
applyQuery:[NSDictionary dictionaryWithObject:ulrRequest
forKey:#"request"]]
applyAnimated:YES]];
Now the last part, to trigger this from a TTTableViewController...
You have in your ViewController to implement :
- (void)didSelectObject:(id)object atIndexPath:(NSIndexPath*)indexPath {
// there you retrieve a *TTTableItem* corresponding to your row
// and call previous snippet from URL...
// TTTableItem class has userInfo property you could use:
TTTableItem *item = (TTTableItem *)object;
NSString *htmlFile = item.userInfo.
[self openLocalHtmlFile:htmlFile];
}
Hope that helps!
Nothing tested, at all, should not compile or whatsoever, but that is a solution.
That's a solution using basic three20 + iOS features. You could also write a TTCustomWebController inheriting from TTWebController that would take urls like #"myapp://openLocalHtml?file=credits" that's not that hard to do...
...That here is a draft :
#interface TTCustomWebController : TTWebController {}
#end
#implementation TTCustomWebController
- (id)initWithFile:(NSString *)name {
self = [super init];
if (self) {
NSString *filePath = [[NSBundle mainBundle] pathForResource:name ofType:#"html"];
NSURL *URL = [NSURL fileURLWithPath:filePath];
[self openURL:URL];
}
return self;
}
#end
Then you could simply use TTTableLinkedItem in your datasource pointing to these #"myapp://openLocalHtml?file=credits"...
Good luck! :)
I'm using the following code it is working fine if I want to make a HTML page but it is not working on UIWebView. it looks like don't know why web view is not rendering the HTML tags. Is there any way I can fix it?
NSString *htmlString = [NSString stringWithFormat:#"<html><head><style type='text/css'>body { color:#FFFFFF; background-color: #000000; }</style></head><body>%#</body></html>",string];
[webView loadHTMLString:htmlString baseURL:nil];
This code works for me:
- (void)viewDidLoad {
[super viewDidLoad];
NSString *string = [[NSString alloc] initWithFormat:#"Helooooooo"];
NSString *htmlString = [[NSString alloc] initWithFormat:#"<html><head><style type='text/css'>body { color:#FFFFFF; background-color: #000000; }</style></head><body>%#</body></html>", string];
[webView loadHTMLString:htmlString baseURL:nil];
}
Here's a screenshot: