I am using MPMediaPickerController to upload music files. When I tried to convert MPMediaItem to NSData, the NSData always returns NULL.
Here is my code:
- (IBAction)addMusic:(id)sender {
MPMediaPickerController *soundPicker=[[MPMediaPickerController alloc] initWithMediaTypes:MPMediaTypeMusic];
soundPicker.delegate=self;
soundPicker.allowsPickingMultipleItems=NO;
[self presentViewController:soundPicker animated:YES completion:nil];
}
- (void)mediaPicker: (MPMediaPickerController *)mediaPicker didPickMediaItems:(MPMediaItemCollection *)mediaItemCollection{
MPMediaItem *item = [[mediaItemCollection items] objectAtIndex:0];
NSURL *url = [item valueForProperty: MPMediaItemPropertyAssetURL];
NSString *audioFilePath = [NSString stringWithFormat:#"%#",url];
NSData *audioData = [NSData dataWithContentsOfFile:audioFilePath];
[self dismissViewControllerAnimated:YES completion:nil];
}
Please suggest what can I do to convert MPMediaItem to NSData.
Your problem is in these three lines:
NSURL *url = [item valueForProperty: MPMediaItemPropertyAssetURL];
NSString *audioFilePath = [NSString stringWithFormat:#"%#",url];
NSData *audioData = [NSData dataWithContentsOfFile:audioFilePath];
Try doing:
NSURL *url = [item valueForProperty: MPMediaItemPropertyAssetURL];
NSError *error = nil;
NSData *audioData = [NSData dataWithContentsOfURL:url options:nil error:&error];
if(!audioData)
NSLog(#"error while reading from %# - %#", [url absoluteString], [error localizedDescription]);
And see if that works better.
If you're interested, what was wrong with the first block of code there was that [NSString stringWithFormat:#"%#",url] probably gives a nil result, since url is a NSURL object and NSString's format is expecting a NSString object.
Related
I'm using the below to set my imageView with a url (located in path). Yes, the URL data is returned successfully, but for some reason, my imageView remains blank (just white?)
And yes, I've hooked up my imageView property... Any idea what's wrong? Should I be using a different block of code to accomplish this?
Viewcontroller.m
NSMutableDictionary *viewParamsDogs = [NSMutableDictionary new];
[viewParamsDogs setValue:#"mydogs" forKey:#"view_name"];
[DIOSView viewGet:viewParamsDogs success:^(AFHTTPRequestOperation *operation, id responseObject) {
self.dogData = [responseObject mutableCopy];
[operation responseString];
NSDictionary *dic = [responseObject valueForKey: #"field_pet_photo_path"];
NSArray *arr = [dic valueForKey: #"und"];
NSDictionary *dic2= [arr objectAtIndex : 0];
NSString *path = [NSString stringWithFormat:#"%#", [dic2 valueForKey: #"safe_value"]];
NSLog(#"This is path %#", path);
if([path length]>0) {
NSURL *url = [NSURL URLWithString:path];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
self.dogimageView.image = image;
} else {
NSString *ImageURL = #"http://url.ca/paw.png";
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:ImageURL]];
self.dogimageView.image = [UIImage imageWithData:imageData];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Failure: %#", [error localizedDescription]);
}];
Path:
[5111:1673330] This is path (
"http://url.com/default/files/stored/1460659054.jpg"
)
NSLog(#"This is path %#, %#", path, NSStringFromClass(path.class)); returns:
2016-04-14 13:18:39.590 [5225:1700657] This is path (
"http://url.com/default/files/stored/1460659054.jpg"
), __NSCFString
I recommend usage of AFNetworking https://github.com/AFNetworking/AFNetworking for all networking connect features.
Import UIImageView+AFNetworking.h at beginning of file
#import "UIImageView+AFNetworking.h"
Get path from dic2
NSString *path = dic2[#"safe_value"];
Check if path is a string
if (![path isKindOfClass:[NSString class]]) {
return;
}
Create a NSURL object from string
NSURL *imageUrl = [NSURL URLWithString:path];
Set imageUrl to UIImageView
[self.dogimageView setImageWithURL:imageUrl];
You could check the full code in my gist https://gist.github.com/MaciejGad/fa8cb80dfc73ea55edeedb75418ea2ec
Edit:
the reason of error was the path that was set as:
NSString *path = #"(
\"http://url.com/default/files/stored/1460659054.jpg\"
)";
to change to normal URL we need to trim it:
NSMutableCharacterSet *characterSetToTrim = [NSMutableCharacterSet characterSetWithCharactersInString:#"()\""];
[characterSetToTrim formUnionWithCharacterSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
path = [path stringByTrimmingCharactersInSet:characterSetToTrim];
after this trimming path should be http://url.com/default/files/stored/1460659054.jpg
Try like this,
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
self.dogimageView.image = [[UIImageView alloc] initWithImage:image];
and You can use great library SDWebImage for caching image. When image comes from server use of this library is very helpful. Hope this will work.
Update :
NSString *path = [NSString stringWithFormat:#"%#", [dic2 valueForKey: #"safe_value"]];
NSURL *url = [NSURL URLWithString:path];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
self.dogimageView.image = [[UIImageView alloc] initWithImage:image];
Try this. :)
Try using dataWithContentsOfURL:options:error: instead and look if there is any error message there
I want save json file from server each time, when user have internet connection to use it when iPhone doesnt have internet connection. But it doesn't working. Here is my code:
- (void)writeJsonToFile
{
//applications Documents dirctory path
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
//live json data url
NSString *stringURL = #"http://volodko.info/ic/json.php";
NSURL *url = [NSURL URLWithString:stringURL];
NSData *urlData = [NSData dataWithContentsOfURL:url];
//attempt to download live data
if (urlData)
{
NSString *filePath = [NSString stringWithFormat:#"%#/%#", documentsDirectory,#"data.json"];
[urlData writeToFile:filePath atomically:YES];
}
//copy data from initial package into the applications Documents folder
else
{
//file to write to
NSString *filePath = [NSString stringWithFormat:#"%#/%#", documentsDirectory,#"data.json"];
//file to copy from
NSString *json = [ [NSBundle mainBundle] pathForResource:#"data" ofType:#"json" inDirectory:#"html/data" ];
NSData *jsonData = [NSData dataWithContentsOfFile:json options:kNilOptions error:nil];
//write file to device
[jsonData writeToFile:filePath atomically:YES];
}
}
try this . . .
- (void)writeJsonToFile
{
//applications Documents dirctory path
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
//live json data url
NSString *stringURL = #"http://volodko.info/ic/json.php";
NSURL *url = [NSURL URLWithString:stringURL];
NSData *urlData = [NSData dataWithContentsOfURL:url];
//attempt to download live data
if (urlData)
{
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"data.json"];
[urlData writeToFile:filePath atomically:YES];
}
//copy data from initial package into the applications Documents folder
else
{
//file to write to
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"data.json"];;
//file to copy from
NSString *json = [ [NSBundle mainBundle] pathForResource:#"data" ofType:#"json" inDirectory:#"html/data" ];
NSData *jsonData = [NSData dataWithContentsOfFile:json options:kNilOptions error:nil];
//write file to device
[jsonData writeToFile:filePath atomically:YES];
}
}
This works for me. Read the AFJSONRequestOperation guide. The code also checks if the json-file already have been cached.
NSString *path = #"http://volodko.info/ic/json.php";
NSURL *url = [[NSURL alloc] initWithString:path];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
id cachedJson = [[NSUserDefaults standardUserDefaults] valueForKey:path];
if (cachedJson) {
[self didUpdateJSON:cachedJson];
} else {
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
[self didUpdateJSON:JSON];
dispatch_async(dispatch_get_main_queue(), ^{
[[NSUserDefaults standardUserDefaults] setObject:JSON forKey:path];
[[NSUserDefaults standardUserDefaults] synchronize];
});
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
NSLog(#"Request Failed with Error: %#, %#", error, error.userInfo);
}];
[operation start];
}
Fetch data from JSON parser and store it in an array. After that you can add it to a SQLite database.
You should create path in proper way
replace this
NSString *filePath = [NSString stringWithFormat:#"%#/%#", documentsDirectory,#"data.json"];
with
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"data.json"];
Anton , fetch the json data and store in the nsmutable array at the first time you Array hold the data when u run again ur array not a nil but replay the data to the second time ... and another way to store the data in local database...if u r needed to store the data..
but ur problem is solve for first one..ok best of luck..
Try using NSUserDefaults instead of writing this small JSON text to a file
- (void)writeJsonToFile
{
NSString *jsonString;
NSString *stringURL = #"http://volodko.info/ic/json.php";
NSURL *url = [NSURL URLWithString:stringURL];
NSData *urlData = [NSData dataWithContentsOfURL:url];
if (urlData)
{
// JSON successfully downloaded, store it to user defaults
jsonString = [[NSString alloc] initWithData:urlData encoding:NSUTF8StringEncoding];
[[NSUserDefaults standardUserDefaults] setValue:jsonString forKey:#"jsonString"];
}
else
{
// no urlData, using stored JSON
jsonString = [[NSUserDefaults standardUserDefaults] valueForKey:#"jsonString"];
}
}
possibly even better:
- (NSString *)getJSON
{
<the code above>
return jsonString;
}
and then use it in other functions as:
NSString *jsonString = [self getJSON];
I'm trying to stream an radio in my app.
I'm using AVAudioPlayer, but I have an error I don't understand :
NSString *urlString = #"http://broadcast.infomaniak.net/radionova-high.mp3";
NSURL *myURL = [NSURL URLWithString:urlString];
NSError *error;
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:myURL error:&error];
if (self.audioPlayer == nil){
NSLog(#"Error loading clip: %#", [error localizedDescription]);
}
else {
self.audioPlayer.delegate = self;
self.audioPlayer.volume = 0.5;
[self.audioPlayer play];
}
And I have the following error :
Error loading clip: The operation couldn’t be completed. (OSStatus error -43.)
Does anyone see what's wrong ?
EDIT :
This is what the Apple docs say:
The AVAudioPlayer class does not provide support for streaming audio
based on HTTP URL's. The URL used with initWithContentsOfURL: must be
a File URL (file://). That is, a local path.
Now what ? :(
download file to document directoty then play file
NSString *urlString = #"http://broadcast.infomaniak.net/radionova-high.mp3";
NSURL *myURL = [NSURL URLWithString:urlString];
NSData *audioData = [NSData dataWithContentsOfURL:myURL];
NSString *docDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:#"%#/%#.mp3", docDirPath , fileName];
[audioData writeToFile:filePath atomically:YES];
NSError *error;
NSURL *fileURL = [NSURL fileURLWithPath:filePath];
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:&error];
if (self.audioPlayer == nil) {
NSLog(#"AudioPlayer did not load properly: %#", [error description]);
} else {
self.audioPlayer.delegate = self;
self.audioPlayer.volume = 0.5;
[self.audioPlayer play];
}
I am trying to save data into a directory created by NSFileManager but when I try and retrieve the data and NSLog it I get null. Also, when you create a directory does that mean you create a folder at a specified url path? Heres the code I am using
NSError *error = nil;
NSFileManager *manager = [[NSFileManager alloc] init];
NSArray *urlsArray = [manager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
NSLog(#"%#", urlsArray);
// This will create a new url and append a photo title to the end
NSURL *url = [[urlsArray lastObject] URLByAppendingPathComponent:[NSString stringWithFormat:#"%#", [self.recentPhoto objectForKey:FLICKR_PHOTO_TITLE]]];
NSLog(#"%#", url);
NSString *urlString = [NSString stringWithFormat:#"%#", [url absoluteString]];
NSLog(#"%#", urlString);
//create the directory
if(![manager fileExistsAtPath:urlString isDirectory:YES]){
BOOL success = [manager createDirectoryAtURL:url withIntermediateDirectories:YES attributes:nil error:&error];
if (!success) {
NSLog(#"Error creating data path: %#", [error localizedDescription]);
}
}
//get url for a photo image and then store it.
NSURL *imageURL = [FlickrFetcher urlForPhoto:self.recentPhoto format:FlickrPhotoFormatLarge];
NSData *imageData = [[NSData alloc] initWithContentsOfURL:imageURL];
[imageData writeToURL:url atomically:YES];
//get data to check if its stored
NSData *checkImageData = [[NSData alloc] initWithContentsOfURL:url];
//This returns null
NSLog(#"%#", checkImageData);
//this returns 0
NSLog(#"%d", [manager isReadableFileAtPath:urlString]);
There are several issues with your code.
This:
NSURL *url = [[urlsArray lastObject] URLByAppendingPathComponent:[NSString stringWithFormat:#"%#", [self.recentPhoto objectForKey:FLICKR_PHOTO_TITLE]]];
should be:
NSURL *url = [[urlsArray lastObject] URLByAppendingPathComponent:[self.recentPhoto objectForKey:FLICKR_PHOTO_TITLE]];
This:
NSString *urlString = [NSString stringWithFormat:#"%#", [url absoluteString]];
should be:
NSString *urlString = [url path];
This:
BOOL success = [manager createDirectoryAtURL:url withIntermediateDirectories:YES attributes:nil error:&error];
should be:
BOOL success = [manager createDirectoryAtURL:[url URLByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:nil error:&error];
This:
[imageData writeToURL:url atomically:YES];
should be:
NSError *error = nil;
BOOL res = [imageData writeToURL:url options:NSDataWritingAtomic error:&error];
if (!res) {
NSLog(#"Unable to write to %#: %#", url, error);
}
The primary issue was the use of absoluteString instead of path to convert the URL to a file path. Secondary was passing the filename instead of the path when creating the directory. The needless use of stringWithFormat: didn't cause any issues but please break that habit now. Only use stringWithFormat: when you actually need to format a string. It is NOT needed to assign a string to a string variable.
You didn't specify a file name for your image inside the directory, this can be solved by adding this line right after the directory is created :
// Right after the directory is created (I suppose the format is png) :
url = [url URLByAppendingPathComponent:#"image.png"];
// Now you can continue with the rest of your code :
//get url for a photo image and then store it.
NSURL *imageURL = [FlickrFetcher urlForPhoto:self.recentPhoto format:FlickrPhotoFormatLarge];
NSData *imageData = [[NSData alloc] initWithContentsOfURL:imageURL];
[imageData writeToURL:url atomically:YES];
//get data to check if its stored
NSData *checkImageData = [[NSData alloc] initWithContentsOfURL:url];
//This returns null
NSLog(#"%#", checkImageData);
//this returns 0
NSLog(#"%d", [manager isReadableFileAtPath:urlString]);
I have never created an instance of a file manager. I have always simply used the default.
See if this helps:
NSFileManager *manager = [NSFileManager defaultManager];
i try to send a audio record by file aac (kAudioFormatMPEG4AAC) format but the file attached it's doesn't send
*myString = file://localhost/private/var/mobile.......
here is my code
MFMailComposeViewController *picker =
[[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
[picker setSubject:#"My Audio File"];
NSString *fileName = #"Rec.aac";
NSString *documentsDirectory = myString ;
NSString *path = [documentsDirectory stringByAppendingPathComponent:fileName];
NSData *data = [NSData dataWithContentsOfFile:path];
[picker addAttachmentData:data mimeType:#"audio/aac"
fileName:fileName];
NSString *emailBody = #"AAC format sound file attached.";
[picker setMessageBody:emailBody isHTML:YES];
[self presentModalViewController:picker animated:YES];
[picker release];
NSData *data = [NSData dataWithContentsOfFile:path];
You're passing in a file:// URL, which won't be understood by that method. That method expects just a standard file path, i.e. /private/var/mobile/.
You could simply use the file path, but if you're only provided with a URL form string, you can create a URL object and use that with NSData.
NSURL* fileURL = [NSURL URLwithString:myString];
NSError* error = nil;
NSData* data = [NSData dataWithContentsOfURL:fileURL options:0 error:&error];
if (error) {
NSLog(#"Unable to load file from provided URL %#: %#", myString, error);
}