Basically I need to know how a webview knows what kind of file extension is being tapped, (png, zip, etc) and then push another view controller.
I have tried this before without the file extension code and it will push another view just fine.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if(navigationType == UIWebViewNavigationTypeLinkClicked) {
NSURL *theRessourcesURL = [request URL];
DetailViewController *vc = [[DetailViewController alloc] init];
[vc downloadURL:theRessourcesURL userInfo:nil];
[self.navigationController pushViewController:vc animated:YES];
dlvc.delegate = self;
}
return YES;
}
Non-working code:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if(navigationType == UIWebViewNavigationTypeLinkClicked) {
NSURL *theRessourcesURL = [request URL];
NSString *fileExtension = [theRessourcesURL pathExtension];
if ([fileExtension isEqualToString:#"png"]) {
MYViewController *vc = [[MYViewController alloc] init];
[dlvc downloadURL:theRessourcesURL userInfo:nil];
[self.navigationController pushViewController:vc animated:YES];
vc.delegate = self;
}
else{}
}
return YES;
}
Working for the most part.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if(navigationType == UIWebViewNavigationTypeLinkClicked) {
NSURL *theRessourcesURL = [request URL];
NSString *fileExtension = [theRessourcesURL pathExtension];
NSLog(#"fileExtension is: %#", fileExtension);
if ([fileExtension isEqualToString:#"php"] || [fileExtension isEqualToString:#".png"] || [fileExtension isEqualToString:#".zip"] || [fileExtension isEqualToString:#".deb"] || [fileExtension isEqualToString:#".jpg"] || [fileExtension isEqualToString:#".mp3"]) {
NSError *error = nil; //error setting
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:#"Downloads"];
if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
[[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:&error]; //Create folder
HCDownloadViewController *dlvc = [[HCDownloadViewController alloc] init];
[dlvc downloadURL:theRessourcesURL userInfo:nil];
[self.navigationController pushViewController:dlvc animated:YES];
dlvc.delegate = self;
return NO;
}
else{}
}
return YES;
}
I also tried to use this as a starter base without success, as I don't use interface builder, so I don't know if IBActions can be used (if they can I dont know how to implement them properly). How to download files from UIWebView and open again
Any help would be appreciated.
Maybe you should put your if ([fileExtension isEqualToString:#"png"] || ...) inside if(navigationType == UIWebViewNavigationTypeLinkClicked){} and try again?
Related
I use this method inside an NSOperation for check and create a folder:
- (void) checkAndCreateFolderWithPath:(NSString *)path {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *pathDaControllare = [[self getLibraryPath] stringByAppendingPathComponent:path];
NSError *error = nil;
BOOL isDir;
BOOL exists = [fileManager fileExistsAtPath:pathDaControllare isDirectory:&isDir];
if (exists) {
if (isDir) {
}
}
else {
[fileManager createDirectoryAtPath:pathDaControllare
withIntermediateDirectories:YES
attributes:nil
error:&error];
NSLog(#"%#",error);
}
}
Using NSOperation I get this error:
Error Domain=NSCocoaErrorDomain Code=512 "The operation couldn’t be completed.
if I don't use NSOperation all work perfectly, this is the nsoperation
- (void) main {
NSString *filePath = [fileDict objectForKey:#"url"];
NSString *urlStr = [NSString stringWithFormat:#"http://www.allmyapp.net/wp-content/iFormulario_Update/%#",filePath];
urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:urlStr]];
[NSURLConnection sendAsynchronousRequest:urlRequest
queue:[[NSOperationQueue alloc] init]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
if (data) {
NSString *folderPath = [filePath stringByReplacingOccurrencesOfString:[filePath lastPathComponent] withString:#""];
[self checkAndCreateFolderWithPath:folderPath];
NSString *pathFile = [[self getLibraryPath] stringByAppendingString:filePath];
[data writeToFile:pathFile atomically:YES];
[self addSkipBackupAttributeToItemAtURL:[NSURL URLWithString:pathFile]];
[[NSNotificationCenter defaultCenter] postNotificationName:#"endFile" object:nil];
[self willChangeValueForKey:#"isFinished"];
[self willChangeValueForKey:#"isExecuting"];
isExecuting = NO;
isFinished = YES;
[self didChangeValueForKey:#"isExecuting"];
[self didChangeValueForKey:#"isFinished"];
}
}];
}
And this the method for create the queue:
for (NSDictionary *dict in fileDaScaricare) {
DownloadOperation *downloadOperation = [[DownloadOperation alloc] initWithDictionary:dict];
[self.operationQueue addOperation:downloadOperation];
}
You can try something like this:
NSString *stringPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]stringByAppendingPathComponent:#"/MyFolder"];
NSError *error = nil;
if (![[NSFileManager defaultManager] fileExistsAtPath:stringPath])
[[NSFileManager defaultManager] createDirectoryAtPath:stringPath withIntermediateDirectories:NO attributes:nil error:&error];
NSString *docFolderPath = [stringPath stringByAppendingString:[NSString stringWithFormat: #"/%#", self.downloadedFilename]];
[data writeToFile:docFolderPath atomically:YES];
It worked for me, and I am able to download a file in MyFolder. Hope it works for you. Please let me know if it works.
I have a webview and download manager implemented into my webview. I have successfully established a action sheet to determine file extensions then shoot a download or cancel buttons. However when i tap download it only downloads the text, not the full file. If I put that download control method in the shouldStartLoadWithRequest section, it downloads the full file, but I have no action sheet appear. Below is the 2 sections of code I'm working with. Any info would be appreciated.
//Download manager
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if(navigationType == UIWebViewNavigationTypeLinkClicked) {
NSURL *theResourcesURL = [request URL];
NSString *fileExtension = [theResourcesURL pathExtension];
NSLog(#"fileExtension is: %#", fileExtension);
if ([fileExtension hasSuffix:#"zip"] || [fileExtension hasSuffix:#"deb"] || [fileExtension hasSuffix:#"rar"] || [fileExtension hasSuffix:#"mp3"] || [fileExtension hasSuffix:#"pdf"] || [fileExtension hasSuffix:#"exe"] || [fileExtension hasSuffix:#"mp4"] || [fileExtension hasSuffix:#"flv"] || [fileExtension hasSuffix:#"torrent"] || [fileExtension hasSuffix:#"png"] || [fileExtension hasSuffix:#"jpg"] || [fileExtension hasSuffix:#"jpeg"]) {
//Action sheet
UIActionSheet *actionSheet = [[[UIActionSheet alloc] initWithTitle:[[self->webView.request URL] absoluteString]
delegate:self
cancelButtonTitle:NSLocalizedString(#"Cancel", #"Action sheet cancel button")
destructiveButtonTitle:nil
otherButtonTitles:
NSLocalizedString(#"Download", #"Action sheet button"),
nil]
autorelease];
[actionSheet showFromToolbar:self.navigationController.toolbar];
//Error setting
NSError *error = nil;
// Get documents folder
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:#"downloads"];
//Create folder
if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
[[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:&error];
}
return NO;
}
return YES;
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if(buttonIndex != actionSheet.cancelButtonIndex) {
NSInteger adjustedIndex = buttonIndex - actionSheet.firstOtherButtonIndex;
switch(adjustedIndex) {
case 0:;
NSURL *theResourcesURL = self->webView.request.URL;
//Download controller
HCDownloadViewController *dlvc = [[HCDownloadViewController alloc] init];
[dlvc downloadURL:theResourcesURL userInfo:nil];
dlvc.delegate = self;
//Configure download view controller
[self.navigationController setNavigationBarHidden:NO];
self.navigationController.navigationBar.tintColor = [UIColor colorWithRed:0/255.0f green:0/255.0f blue:0/255.0f alpha:1];
[self.navigationController pushViewController:dlvc animated:YES]; break;
}
}
}
I try to download a pdf from server and this is my code
ASIHTTPRequest *req = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:[GlobalMethod convertURL:[NSString stringWithFormat:#"%#%#",SITE_IMAGE_URL,pview.nameLable.text]]]];
NSString *documentDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
// Add your filename to the directory to create your saved pdf location
NSString *pdfLocation = [documentDirectory stringByAppendingPathComponent:#"test.pdf"];
// TEMPORARY PDF PATH
// Get the Caches directory
NSString *cachesDirectory = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
// Add your filename to the directory to create your temp pdf location
NSString *tempPdfLocation = [cachesDirectory stringByAppendingPathComponent:#"test.pdf"];
req.shouldContinueWhenAppEntersBackground = YES;
req.delegate = self;
req.downloadProgressDelegate = pview.progressView;
[req setDidFinishSelector:#selector(requestDone:)];
[req setDidFailSelector:#selector(requestWentWrong:)];
[req setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys:pview.nameLable.text,REQ_FILE_NAME, nil]];
[req setTemporaryFileDownloadPath:tempPdfLocation];
[req setDownloadDestinationPath:pdfLocation];
[req startAsynchronous];
it didn't save file to the destination path when the delegate set to self but it work correctly when I comment this line
req.delegate = self;
I really need the delegate to be set
what should I do ?
I found the problem and solve it. It's all happened because of a simple if else. In
ASIHTTPRequest.m
in
-(void)handleBytesAvailable
method you have this code in
// Does the delegate want to handle the data manually?
if (dataWillBeHandledExternally) {
NSData *data = nil;
if ([self isResponseCompressed] && ![self shouldWaitToInflateCompressedResponses]) {
data = inflatedData;
} else {
data = [NSData dataWithBytes:buffer length:bytesRead];
}
[self performSelectorOnMainThread:#selector(passOnReceivedData:) withObject:data waitUntilDone:[NSThread isMainThread]];
// Are we downloading to a file?
}else if ([self downloadDestinationPath]) {
BOOL append = NO;
if (![self fileDownloadOutputStream]) {
if (![self temporaryFileDownloadPath]) {
[self setTemporaryFileDownloadPath:[NSTemporaryDirectory() stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]]];
} else if ([self allowResumeForFileDownloads] && [[self requestHeaders] objectForKey:#"Range"]) {
when you delete the else before the second if and change it to
// Does the delegate want to handle the data manually?
if (dataWillBeHandledExternally) {
NSData *data = nil;
if ([self isResponseCompressed] && ![self shouldWaitToInflateCompressedResponses]) {
data = inflatedData;
} else {
data = [NSData dataWithBytes:buffer length:bytesRead];
}
[self performSelectorOnMainThread:#selector(passOnReceivedData:) withObject:data waitUntilDone:[NSThread isMainThread]];
// Are we downloading to a file?
}if ([self downloadDestinationPath]) {
BOOL append = NO;
if (![self fileDownloadOutputStream]) {
if (![self temporaryFileDownloadPath]) {
[self setTemporaryFileDownloadPath:[NSTemporaryDirectory() stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]]];
} else if ([self allowResumeForFileDownloads] && [[self requestHeaders] objectForKey:#"Range"]) {
it work correctly with delegate and also save to this
I'm following foursquare authen guideline but I still have a problem
this is my code
- (void)viewDidLoad
{
[super viewDidLoad];
self.webView.delegate = self;
NSString *clientID = #"XXX";
NSString *redirectURI = #"http://www.example.com";
NSString *authenticateURLString = [NSString stringWithFormat:#"https://foursquare.com/oauth2/authenticate?client_id=%#&response_type=token&redirect_uri=%#", clientID, redirectURI];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:authenticateURLString]];
[self.webView loadRequest:request];
}
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if ([request.URL.scheme isEqualToString:#"itms-apps"]) {
[[UIApplication sharedApplication] openURL:request.URL];
return NO;
}
return YES;
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
NSString *URLString = [[self.webView.request URL] absoluteString];
NSLog(#"--> %#", URLString);
if ([URLString rangeOfString:#"access_token="].location != NSNotFound) {
NSString *accessToken = [[URLString componentsSeparatedByString:#"="] lastObject];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:accessToken forKey:#"access_token"];
[defaults synchronize];
[self dismissViewControllerAnimated:YES completion:nil];
}
}
but output from NSLog is only http://www.example.com. It has no access token return. Am i do anything wrong?
I'm open this link in Desktop Google Chrome and access token is successfully return. (www.example.com#access_token=XXX)
But I'm open this link in iPhone simulator's safari and it just return the url.
Thanks for help.
#nearonline
I have the same problem, and the reason is the URL in webViewDidFinishLoading will not contain the access token. But the URL in shouldStartLoadWithRequest will. Therefore you should modify the code into:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSString *URLString = [[request URL] absoluteString];
if ([URLString rangeOfString:#"access_token="].location != NSNotFound) {
NSString *accessToken = [[URLString componentsSeparatedByString:#"="] lastObject];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:accessToken forKey:#"access_token"];
[defaults synchronize];
[self dismissViewControllerAnimated:YES completion:nil];
return NO;
}
return YES;
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
}
I'm trying to preview a downloaded file to system and the program crashes when performing the method called previewController:previewItemAtIndex:. From what I assumed is that is releasing the previewcontroller before it is displayed, but this error does not occur when the file is already in the documents folder. It only happens when trying to open the file right after it has been downloaded.
Here is the code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSUInteger row = [indexPath row];
NSUInteger count = [listSessionsST count];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
Signature *object = [listSessionsST objectAtIndex:row];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
UILabel *lblInComplete = (UILabel*)[cell viewWithTag:4];
UIImageView *imgCheck = (UIImageView*)[cell viewWithTag:3];
//Sets the File Name
self.File = [[[NSString stringWithFormat:#"%#_%#.%#",object.FileName,object.ModDate,object.Extension]
componentsSeparatedByCharactersInSet: [NSCharacterSet whitespaceCharacterSet]] componentsJoinedByString: #""];
//Shows the loading screen while the file is being downloaded
[DejalBezelActivityView activityViewForView:self.view withLabel:#"Downloading" width:0 LoadingType:#"Full"];
[DejalActivityView currentActivityView].showNetworkActivityIndicator = YES;
//Calls the method that will begin downloading the file
[self performSelector:#selector(startDownload:) withObject:object.Location afterDelay:0.2];
}
- (void)startDownload:(NSString *)strLocation{
NSString *filePath = [NSString stringWithFormat:#"%#/tmp/%#", NSHomeDirectory(),self.File];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:filePath];
if (fileExists)
{
[DejalBezelActivityView removeViewAnimated:YES];
//QuickLook APIs directly to preview the document
QLPreviewController *previewController = [[QLPreviewController alloc] init];
previewController.dataSource = self;
previewController.delegate = self;
[[self navigationController] pushViewController:previewController animated:YES];
[previewController release];
}
else
{
NSDictionary *dictionary = [Signature downloadFile:self.File Path:strLocation];
if ([dictionary valueForKey:#"Error"] == nil)
{
//If no error has occurred while downloading then preview the file.
//QuickLook APIs directly to preview the document
QLPreviewController *previewController = [[QLPreviewController alloc] init];
previewController.dataSource = self;
previewController.delegate = self;
[[self navigationController] pushViewController:previewController animated:YES];
[previewController release];
[DejalBezelActivityView removeViewAnimated:YES];
}
else
{
//If an error occurred while downloading then display message to user.
[DejalBezelActivityView removeViewAnimated:YES];
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#""
message:[dictionary valueForKey:#"Response"]
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alert show];
[alert release];
}
}
}
// Returns the number of items that the preview controller should preview
- (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController *)previewController{
return 1;
}
// returns the item that the preview controller should preview
- (id)previewController:(QLPreviewController *)controller previewItemAtIndex:(NSInteger)index{
NSString *path = [NSString stringWithFormat:#"%#/tmp/%#", NSHomeDirectory(),self.File];
return [NSURL fileURLWithPath:path];
}
The method that downloads the file and saves it to the tmp folder
---------------------------------------------------------------
+ (NSDictionary *)downloadFile:(NSString *)strFile Path:(NSString *)strPath{
float freeSpace = 0.0f;
NSError *error = nil;
NSDictionary *dictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:[NSString stringWithFormat:#"%#/tmp", NSHomeDirectory()]
error: &error];
if (dictionary)
{
NSNumber *fileSystemFreeSizeInBytes = [dictionary objectForKey: NSFileSystemFreeSize];
freeSpace = [fileSystemFreeSizeInBytes floatValue];
}
else
{
//Handle error
NSLog(#"Error;%#",error);
return [NSDictionary dictionaryWithObjectsAndKeys:#"An error has occurred while downloading the file.",#"Response",#"Y",#"Error", nil];
}
if (freeSpace > 0.0f)
{
NSDictionary *dict = nil;
BOOL blnHasErroroccurred = NO;
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSString *encoded = (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
(CFStringRef)strPath,
NULL,
(CFStringRef)#"!*'\"();:#&=+$,/?%#[]%",
kCFStringEncodingUTF8 );
NSString *strURL = [NSString stringWithFormat:#"%#/DataTransfer/DownloadFile?EMP_ID=%#&FilePath=%#",
appDelegate.ServerAddress,
appDelegate.UserId,
encoded];
[encoded release];
NSURL *url = [NSURL URLWithString:strURL];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
cachePolicy: NSURLRequestUseProtocolCachePolicy
timeoutInterval:20.0];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
NSURLResponse* response = nil;
NSError* resultError = nil;
NSData* dataResult = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&resultError];
NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
if ([httpResponse statusCode] == 200)
{
#try
{
if (dataResult.length < freeSpace)
{
//Get the tmp directory
NSFileManager *fileManager =[NSFileManager defaultManager];
NSString *fileName = [NSString stringWithFormat:#"%#/tmp/%#", NSHomeDirectory(),strFile];
//Write the data to using the tmp directory
BOOL filecreationSuccess = [fileManager createFileAtPath:fileName contents:dataResult attributes:nil];
if(filecreationSuccess == YES)
{
dict = [NSDictionary dictionaryWithObjectsAndKeys:#"",#"Response",nil,#"Error", nil];
}
else
{
blnHasErroroccurred = YES;
}
}
}
#catch (NSException *exception)
{
blnHasErroroccurred = YES;
}
}
else
{
blnHasErroroccurred = YES;
}
if(blnHasErroroccurred == YES)
{
dict = [NSDictionary dictionaryWithObjectsAndKeys:#"An error has occurred while downloading the file.", #"Response", #"Yes",#"Error",nil];
}
[dataResult release];
return dict;
}
else
{
return [NSDictionary dictionaryWithObjectsAndKeys:#"Not enough disk space to download file.",#"Response",#"Y",#"Error", nil];
}
}