Webview action button not downloading full file - ios

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;
}
}
}

Related

iOS 9 Making Code go Sequentially (Touch ID)

I am a developer using self-taught Objective-C to code for the iPhone. We are using Xcode 7 and iOS 9. I am tasked with creating an app for my company to communicate when someone arrives and leaves an appointment in a schedule made for them (using XML).
We would like to use Touch ID for security so the users don’t have to log in a lot. Security is required because of the confidentiality of the data in the app. I had the application working. Or it looked like it worked, until I clicked on the Cancel option in Touch ID and realized that the Touch ID was providing no security.
I believe this is because the methods that are supposed to run after Touch ID were outside of the LA Context block. I put them outside because I need to return a string value on a successful authorization (an internal employee number retrieved through XML). If I put the methods with the returned NSStrings outside of the LA Context block, the methods run in the wrong order.
How can I make the following 4 methods run in sequential order?
1)requireLogin (Touch ID code here)
2)requestSession
3)readSession
4)checkSession
If the Touch ID fails, methods 2-4 should not run.
I’ve looked at blocks. I’ve looked at GCD. I can’t find any examples on how to deal with this. If someone could point me in the right direction. I would really appreciate it. If I need to include more of the code, please let me know.
Thank you in advance.
- (NSString *)retrieveESN {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *directoryPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [directoryPaths objectAtIndex:0];
NSString *fullPath = [documentsDirectoryPath stringByAppendingString:#"/session.txt"];
if ([fileManager fileExistsAtPath:fullPath]==YES) {
_finished = false;
NSLog(#"File exists");
[self readSession];
NSLog(#"%#", _sessionDetail);
NSLog(#"Pre Check Session");
NSString *result = [self checkSession:_sessionDetail];
NSLog(#"Post Check Session");
NSLog(#"%#", result);
if ([result isEqualToString:#"Error"]) {
NSLog(#"Error received - going into newFile");
NSString *userESN = [self newFile];
NSLog(#"Error'd returning with result");
NSLog(#"UserESN: %#", userESN);
return userESN;
} else {
NSLog(#"No Error Received");
NSLog(#"Returning result: %#", result);
return result;
}
} else {
_finished = false;
NSLog(#"No file exists, call newFile");
NSString *userESN = [self newFile];
NSLog(#"UserESN: %#", userESN);
return userESN;
}
}
- (NSString *)newFile {
NSLog(#"File does not exist.");
[self requireLogin];
NSLog(#"Out of requireLogin");
[self requestSession];
NSLog(#"Out of requestSession");
[self readSession];
NSLog(#"Out of readSession");
NSString *userESN = [self checkSession:_sessionDetail];
NSLog(#"Into checkSession again newfile");
return userESN;
}
- (void)requireLogin {
LAContext *context = [[LAContext alloc] init];
NSError *error = nil;
NSLog(#"Into requireLogin");
if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]) {
// Authenticate User
[context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
localizedReason:#"You must log in to the app."
reply:^(BOOL success, NSError * _Nullable error) {
if (success) {
_finished = true;
NSLog(#"success");
} else {
switch (error.code) {
case LAErrorAuthenticationFailed:
NSLog(#"Authentication Failed");
break;
case LAErrorUserCancel:
NSLog(#"User pressed Cancel button");
break;
case LAErrorUserFallback:
//Return to go to Enter Password not available screen.
NSLog(#"User pressed Enter Password");
break;
default:
NSLog(#"Touch ID is not configured");
break;
}
NSLog(#"Authentication Fails");
}
}];
} else {
NSLog(#"Phone doesn't support Touch ID.");
}
}
- (void)requestSession {
NSString *idfv = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
NSString *url = #“https://companyurl.com/session_page”;
NSLog(#"Got to requestSession");
NSMutableString *postText = [[NSMutableString alloc] init];
NSLog(#"%#", idfv);
[postText appendString:idfv];
NSString *postBody = [NSString stringWithString:postText];
XMLPostSecurity *postAction = [[XMLPostSecurity alloc] init];
NSLog(#"Got to PostAction");
_sessionDetail = [postAction sendPostRequestToUrl:url withBody:postBody];
NSLog(#"Session Detail: %#", _sessionDetail);
FileSaving *saver = [[FileSaving alloc] init];
[saver saveSession:self.sessionDetail];
NSLog(#"Saved file.");
}
-(NSString *)readSession {
NSLog(#"In to readSession.");
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *directoryPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [directoryPaths objectAtIndex:0];
NSString *fullPath = [documentsDirectoryPath stringByAppendingString:#"/session.txt"];
while ([fileManager fileExistsAtPath:fullPath]==NO);
NSFileManager *fileManagerTwo;
NSData *dataBuffer;
fileManagerTwo = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingString:#"/session.txt"];
NSLog(#"Got Path");
dataBuffer = [fileManagerTwo contentsAtPath:filePath];
NSLog(#"databuffer created");
_sessionDetail = [[NSString alloc] initWithData:dataBuffer encoding:(NSASCIIStringEncoding)];
NSLog(#"File read: %#", _sessionDetail);
return _sessionDetail;
}
-(NSString *)checkSession:(NSString *)sessionFound {
NSLog(#"Into checkSession");
NSDictionary *cookieProperties = [NSDictionary dictionaryWithObjectsAndKeys:
#"ollie/", NSHTTPCookieDomain,
#"\\", NSHTTPCookiePath,
#"cookieName", NSHTTPCookieName,
sessionFound, NSHTTPCookieValue,
nil];
NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
NSArray *cookieArray = [NSArray arrayWithObject:cookie];
NSDictionary *headers = [NSHTTPCookie requestHeaderFieldsWithCookies:cookieArray];
NSMutableString *url = [[NSMutableString alloc] initWithString:#“https://companyurl.com/xmlfile.php”];
NSLog(#"%#", url);
NSURL *urlNew = [NSURL URLWithString:url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:urlNew];
[request setHTTPMethod:#"GET"];
[request setAllHTTPHeaderFields:headers];
self.parseData = NULL;
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(#"dataTaskWithRequest error: %#", error);
return;
}
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
if (statusCode != 200) {
NSLog(#"dataTaskWithRequest HTTP status code: %ld", (long)statusCode);
if (statusCode == 401) {
// Insert process for thumbprint and session cookie pull
NSLog(#"401 Error received");
NSFileManager *fileManagerThree = [NSFileManager defaultManager];
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *sessionPath = [documentsPath stringByAppendingPathComponent:#"session.txt"];
NSError *error;
BOOL success = [fileManagerThree removeItemAtPath:sessionPath error:&error];
if (success) {
NSLog(#"File deleted - check session.");
} else {
NSLog(#"File could not be deleted.");
}
} else {
NSLog(#"I got something other than 200 or 401");
return;
}
}
}
self.parseData = data;
}];
[task resume];
while ( self.parseData == NULL );
ParseTypeXML *myParser = [[ParseTypeXML alloc] initWithData:self.parseData];
if ([myParser.esn count] == 0) {
return #"Error";
} else {
return myParser.esn[0];
}
}

How can i save video downloaded from url?

i want to save a video that i have downloaded before from URL.
I use this code where when i click on Download Button i will Download the video from the URL. I use the connection method and in the last i save video data using NSFileManager.
The problem is that i create a File path but inside it there aren't any type of data. How can i resolve it?
-(IBAction)download:(id)sender{
/*[downloadButton setEnabled:NO];
[webView setUserInteractionEnabled:NO];*/
//Prendo URL
NSString *getURL = #"";
getURL = [webView stringByEvaluatingJavaScriptFromString:#"function getURL() {var player = document.getElementById('player'); var video = player.getElementsByTagName('video')[0]; return video.getAttribute('src');} getURL();"];
//Prendo il titolo
videoTitle = videoTitleField.text;
NSArray *components = [videoTitle componentsSeparatedByCharactersInSet:[[NSCharacterSet alphanumericCharacterSet] invertedSet]];
videoTitle = [components componentsJoinedByString:#" "];
if ([getURL length] > 0) {
if ([videoTitle length] > 0) {
//videoTitle = [getTitle retain];
fileURL = [NSURL URLWithString:getURL];
downloadUrl = fileURL;
bytesReceived = percentComplete = 0;
localFilename = [[[fileURL absoluteString] lastPathComponent] copy];
receivedData = [[NSMutableData alloc] initWithLength:0];
app.networkActivityIndicatorVisible = YES;
//Inserisco alert view
alert = [[UIAlertView alloc] initWithTitle:#"Download" message:[NSString stringWithFormat:#"%.2f",percentComplete] delegate:nil cancelButtonTitle:nil otherButtonTitles:nil];
[alert show];
//Connessione download
DownloadRequest = [[NSURLRequest alloc] initWithURL:fileURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:15];
DownloadConnection = [[NSURLConnection alloc] initWithRequest:DownloadRequest delegate:self startImmediately:YES];
}
else{
//Utente non inserisce il nome per il video
UIAlertView *alertview = [[UIAlertView alloc] initWithTitle:#"TubeDownloader" message:#"You have to insert a name for the video!" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertview show];
}
}else {
//Non si riesce a prendere URL
UIAlertView *alertView1 = [[UIAlertView alloc] initWithTitle:#"TubeDownloader" message:#"Couldn't get MP4 URL." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView1 show];
[downloadButton setEnabled:YES];
}
}
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
if(!operationBreaked){
[self.receivedData appendData:data];
//[self.receivedData setData:data];
float receivedLen = [data length];
NSLog(#"receive lenght: %f\n",receivedLen);
bytesReceived = (bytesReceived + receivedLen);
if(expectedBytes != NSURLResponseUnknownLength){
//progressView.progress = ((bytesReceived/(float)expectedBytes)*100)/100;
percentComplete = (((bytesReceived/(float)expectedBytes)*100)/100) * 100;
}
NSLog(#"Ricevendo dati..percentuale di completamento:%f",percentComplete);
[alert setMessage:[NSString stringWithFormat:#"Percentage:%.2f",percentComplete]];
}else{
[connection cancel];
NSLog(#"Ricezione dati cancellata...percentuale:%f",percentComplete);
}
[self.receivedData appendData:data];
}
-(void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
operationFailed = YES;
//progressView.progress = 0.0;
}
-(void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
NSLog(#"Bytes aspettati: %f... Bytes ricevuti:%f\n",(float)expectedBytes,(float)bytesReceived);
NSHTTPURLResponse *r = (NSHTTPURLResponse*) response;//An NSHTTPURLResponse object represents a response to an HTTP URL load request. It’s a subclass of NSURLResponse that provides methods for accessing information specific to HTTP protocol responses.
NSDictionary *headers = [r allHeaderFields];//headerFields:a dictionary representing the keys and values from the server’s response header.
NSLog(#"[DO::didReceiveResponse] response headers: %#", headers);
if (headers){
if ([headers objectForKey: #"Content-Range"]) {
NSString *contentRange = [headers objectForKey: #"Content-Range"];
NSLog(#"Content-Range: %#", contentRange);
NSRange range = [contentRange rangeOfString: #"/"];
NSString *totalBytesCount = [contentRange substringFromIndex: range.location + 1];
expectedBytes = [totalBytesCount floatValue];
} else if ([headers objectForKey: #"Content-Length"]) {
NSLog(#"Content-Length: %#", [headers objectForKey: #"Content-Length"]);
expectedBytes = [[headers objectForKey: #"Content-Length"] floatValue];
} else expectedBytes = -1;
if ([#"Identity" isEqualToString: [headers objectForKey: #"Transfer-Encoding"]]) {
expectedBytes = bytesReceived;
operationFinished = YES;
}
}
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
NSLog(#"connessione terminata con successo receive data:%f!!",bytesReceived);
operationFinished = YES;
[alert setMessage:#"Download been succesfully"];
app.networkActivityIndicatorVisible = NO;
//NSData *saveData = [NSData dataWithBytes:&receivedData length:sizeof(receivedData)];
//Attivo timer per dimettere il timer
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(dismissAlert) userInfo:nil repeats:NO];
//[self.receivedData setData:];
//Chiamo la funzione di salvataggio passandogli come NSData receivedata e localfileName
//[self saveVideo:self.receivedData];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *pathdir = [NSString stringWithFormat:#"%#.mp4", [[path objectAtIndex:0] stringByAppendingPathComponent:videoTitle]];
NSLog(#"pathDir: %#",pathdir);
[fileManager createFileAtPath:pathdir contents:receivedData attributes:nil];
NSString *imagePath = [NSString stringWithFormat:#"%#.mp4", [[path objectAtIndex:0]stringByAppendingPathComponent:videoTitle]];
AVAsset *asset = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:[NSString stringWithFormat:#"%#.mp4",[[path objectAtIndex:0] stringByAppendingPathComponent:videoTitle]]] options:nil]; //AVAsset is an abstract class to represent timed audiovisual media such as videos and sounds. Each asset contains a collection of tracks that are intended to be presented or processed together, each of a uniform media type, including but not limited to audio, video, text, closed captions, and subtitles.
AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:asset]; //An AVAssetImageGenerator object provides thumbnail or preview images of assets independently of playback. AVAssetImageGenerator uses the default enabled video track(s) to generate images.
Float64 durationSeconds = CMTimeGetSeconds(asset.duration);
CMTime midpoint = CMTimeMakeWithSeconds(durationSeconds / 2.0, 600);
CMTime actualTime;
CGImageRef preImage = [imageGenerator copyCGImageAtTime:midpoint actualTime:&actualTime error:NULL];
if (preImage != NULL) {
CGRect rect = CGRectMake(0.0, 0.0, CGImageGetWidth(preImage) * 0.5, CGImageGetHeight(preImage) * 0.5);
UIImage *image = [UIImage imageWithCGImage:preImage];
UIGraphicsBeginImageContext(rect.size);
[image drawInRect:rect];
NSData *data = UIImagePNGRepresentation(UIGraphicsGetImageFromCurrentImageContext());
[fileManager createFileAtPath:imagePath contents:data attributes:nil];
UIGraphicsEndImageContext();
}
CGImageRelease(preImage);
//videoTitle = nil;
NSLog(#"Salvataggio con successo");
}

Determine file extension on tap and push view controlelr

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?

QLPreviewController not opening downloaded file

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];
}
}

Application crashed while importing songs from Ipod library in iPhone for iOs 5.0

Hello i am using below framworks,
#import <MediaPlayer/MediaPlayer.h>
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>
In one of button event i have implemented below code to open Library.
MPMediaPickerController *mediaPicker = [[MPMediaPickerController alloc] initWithMediaTypes:MPMediaTypeMusic];
mediaPicker.delegate = self;
mediaPicker.allowsPickingMultipleItems = YES; // this is the default
[self presentModalViewController:mediaPicker animated:YES];
[mediaPicker release];
And in delegate methods of MPMediaPickerController implemented code as below
#pragma mark MPMediaPickerController delegate methods
- (void)mediaPicker: (MPMediaPickerController *)mediaPicker didPickMediaItems:(MPMediaItemCollection *)mediaItemCollection {
// We need to dismiss the picker
[self dismissModalViewControllerAnimated:YES];
// Assign the selected item(s) to the music player and start playback.
counterIpod = [mediaItemCollection.items count];
totalcollection = counterIpod;
if (totalcollection > 10) {
NSString *str = [NSString stringWithFormat:#"App Only supports importing 10 songs at a time"];
UIAlertView *connectionAlert = [[UIAlertView alloc] initWithTitle:#"Message !" message:str delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[connectionAlert show];
[connectionAlert release];
}
else {
[self performSelector:#selector(saveMediaItem:) withObject:mediaItemCollection afterDelay:0.1];
//[self saveMediaItem:mediaItemCollection];
//[self showLoadingView];
}
}
- (void)mediaPickerDidCancel:(MPMediaPickerController *)mediaPicker {
// User did not select anything
// We need to dismiss the picker
[self dismissModalViewControllerAnimated:YES];
}
#pragma mark Sace Item Collection to documentsDirectory
-(void)saveMediaItem:(MPMediaItemCollection *)mediaItemCollection {
for (int i = 0; i < [mediaItemCollection.items count]; i++) {
[self exportAssetAsSourceFormat:[[mediaItemCollection items] objectAtIndex:i]];
NSLog(#"for loop : %d", i);
}
NSArray *itemsArray1 = appDelegate.mediaItemCollection1.items;
MPMediaItemCollection *mediaItemCollection2;
if ([itemsArray1 count] != 0) {
mediaItemCollection2 = [self collectionByAppendingCollection:mediaItemCollection];
}
else {
mediaItemCollection2 = mediaItemCollection;
}
[self saveMediaItemAfterDeletting:mediaItemCollection2];
}
-(void)saveMediaItemAfterDeletting:(MPMediaItemCollection *)mediaItemCollection {
NSMutableData* data = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver encodeObject:mediaItemCollection forKey:#"my_playlist"];
[archiver finishEncoding];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:#"%#/playlist.data", documentsDirectory];
NSLog(#"file path = %#", filePath);
[data writeToFile:filePath atomically:YES];
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]){
NSLog(#"file exists : ===========>>>>>>>>>>>");
} else {
NSLog(#"file doesn't exist");
}
//NSLog(#"archiving playlist success = %d", success);
[archiver release];
[data release];
[self UpdateMediaCollection];
}
-(NSString*) getExtension:(MPMediaItem *)item {
// [self showLoadingView];
NSURL *assetURL = [item valueForProperty:MPMediaItemPropertyAssetURL];
AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:assetURL options:nil];
// JP
// AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]
// initWithAsset:songAsset
// presetName:AVAssetExportPresetPassthrough];
NSArray *tracks = [songAsset tracksWithMediaType:AVMediaTypeAudio];
AVAssetTrack *track = [tracks objectAtIndex:0];
id desc = [track.formatDescriptions objectAtIndex:0];
const AudioStreamBasicDescription *audioDesc = CMAudioFormatDescriptionGetStreamBasicDescription((CMAudioFormatDescriptionRef)desc);
FourCharCode formatID = audioDesc->mFormatID;
//exportAudioMix.inputParameters = [NSArray arrayWithObject:exportAudioMixInputParameters];
//exportSession.audioMix = exportAudioMix;
NSString *fileType = nil;
NSString *ex = nil;
switch (formatID) {
case kAudioFormatLinearPCM:
{
UInt32 flags = audioDesc->mFormatFlags;
if (flags & kAudioFormatFlagIsBigEndian) {
fileType = #"public.aiff-audio";
ex = #"aif";
} else {
fileType = #"com.microsoft.waveform-audio";
ex = #"wav";
}
}
break;
case kAudioFormatMPEGLayer3:
fileType = #"com.apple.quicktime-movie";
ex = #"mp3";
break;
case kAudioFormatMPEG4AAC:
fileType = #"com.apple.m4a-audio";
ex = #"m4a";
break;
case kAudioFormatAppleLossless:
fileType = #"com.apple.m4a-audio";
ex = #"m4a";
break;
default:
break;
}
return ex;
}
#pragma mark Covert Item separate item collection and store songs into directory
- (void)exportAssetAsSourceFormat:(MPMediaItem *)item {
// [self showLoadingView];
NSLog(#"export asset called");
NSURL *assetURL = [item valueForProperty:MPMediaItemPropertyAssetURL];
NSLog(#"\n>>>> assetURL : %#",[assetURL absoluteString]);
AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:assetURL options:nil];
// JP
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]
initWithAsset:songAsset
presetName:AVAssetExportPresetPassthrough];
NSArray *tracks = [songAsset tracksWithMediaType:AVMediaTypeAudio];
AVAssetTrack *track = [tracks objectAtIndex:0];
id desc = [track.formatDescriptions objectAtIndex:0];
const AudioStreamBasicDescription *audioDesc = CMAudioFormatDescriptionGetStreamBasicDescription((CMAudioFormatDescriptionRef)desc);
FourCharCode formatID = audioDesc->mFormatID;
//exportAudioMix.inputParameters = [NSArray arrayWithObject:exportAudioMixInputParameters];
//exportSession.audioMix = exportAudioMix;
NSString *fileType = nil;
NSString *ex = nil;
switch (formatID) {
case kAudioFormatLinearPCM:
{
UInt32 flags = audioDesc->mFormatFlags;
if (flags & kAudioFormatFlagIsBigEndian) {
fileType = #"public.aiff-audio";
ex = #"aif";
} else {
fileType = #"com.microsoft.waveform-audio";
ex = #"wav";
}
}
break;
case kAudioFormatMPEGLayer3:
fileType = #"com.apple.quicktime-movie";
ex = #"mp3";
break;
case kAudioFormatMPEG4AAC:
fileType = #"com.apple.m4a-audio";
ex = #"m4a";
break;
case kAudioFormatAppleLossless:
fileType = #"com.apple.m4a-audio";
ex = #"m4a";
break;
default:
break;
}
exportSession.outputFileType = fileType;
NSString *fileName = nil;
fileName = [NSString stringWithString:[item valueForProperty:MPMediaItemPropertyTitle]];
fileName = [[fileName stringByAppendingString:#"-"] stringByAppendingString:[item valueForProperty:MPMediaItemPropertyArtist]];
NSArray *fileNameArray = nil;
fileNameArray = [fileName componentsSeparatedByString:#" "];
fileName = [fileNameArray componentsJoinedByString:#""];
NSLog(#">>>>> fileName = %#", fileName);
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [[docDir stringByAppendingPathComponent:fileName] stringByAppendingPathExtension:ex];
NSLog(#"filePath = %#", filePath);
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
//NSLog(#"file exist::::::::::==============>>>>>>>>>>>>>>>>>");
counterIpod--;
if(counterIpod == 0) {
//[self showAlertView];
//[self hideLoadingView];
}
NSString *str = [NSString stringWithFormat:#"Loading %d of %d Beats", totalcollection - counterIpod ,totalcollection];
[lbl performSelectorOnMainThread:#selector(setText:) withObject:str waitUntilDone:NO];
//NSLog(#"loading string : %#", str);
return;
}
//NSLog(#"file not exist ===========>>>>>>>>>");
// -------------------------------------
int fileNumber = 0;
NSString *fileNumberString = nil;
NSString *fileNameWithNumber = nil;
while ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
fileNumber++;
fileNumberString = [NSString stringWithFormat:#"-%02d", fileNumber];
fileNameWithNumber = [fileName stringByAppendingString:fileNumberString];
filePath = [[docDir stringByAppendingPathComponent:fileNameWithNumber] stringByAppendingPathExtension:ex];
//NSLog(#"filePath = %#", filePath);
}
// -------------------------------------
myDeleteFile(filePath);
exportSession.outputURL = [NSURL fileURLWithPath:filePath];
[exportSession exportAsynchronouslyWithCompletionHandler:^{
if (exportSession.status == AVAssetExportSessionStatusCompleted) {
NSLog(#"export session completed");
counterIpod--;
NSString *str = [NSString stringWithFormat:#"Loading %d of %d Beats", totalcollection - counterIpod ,totalcollection];
//[self performSelector:#selector(setLabelText:) withObject:str afterDelay:0.02];
[lbl performSelectorOnMainThread:#selector(setText:) withObject:str waitUntilDone:NO];
NSLog(#"loading string : %#", str);
if(counterIpod == 0) {
//[self showAlertView];
//[self hideLoadingView];
}
} else {
NSLog(#"export session error");
counterIpod--;
NSString *str = [NSString stringWithFormat:#"Loading %d of %d Beats", totalcollection - counterIpod ,totalcollection];
[lbl performSelectorOnMainThread:#selector(setText:) withObject:str waitUntilDone:NO];
//return NO;
if(counterIpod == 0) {
//[self showAlertView];
//[self hideLoadingView];
}
}
[exportSession release];
}];
//[appDelegate hideLoadingView];
}
#pragma mark method to delete file from document directory
void myDeleteFile (NSString* path) {
// NSLog(#"file path delete file :::::::::: %#", path);
if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
NSError *deleteErr = nil;
[[NSFileManager defaultManager] removeItemAtPath:path error:&deleteErr];
if (deleteErr) {
NSLog (#"Can't delete %#: %#", path, deleteErr);
}
}
}
Above code work without any error on iOS 4.0 or prior version but for iOS 5.0 is crashes on device, I can't resolve these issues since last 15 days.
Thanks in advance for Help.
I have solved this issues,
just comment out this line
fileName = [[fileName stringByAppendingString:#"-"] stringByAppendingString:[item valueForProperty:MPMediaItemPropertyArtist]];
because for some songs there is null artist so it's crash...................
This is because you are using some songs has artist name while some with blank artist name, so you are trying to append blank name in string that's why app going to crash.
Hope you unserstand what i say...

Resources