Using iPhone audio files in own app - copy the audio file - is that possible? - iphone

I like the user to pick an audio file from the available list of audio and copy it into my own app. In the retrieved items of userMediaItemCollection in the Apple sample code "AddMusic" there is the property: MPMediaItemPropertyAssetURL. But I cant get to it, since I get the error "MPMediaItemPropertyAssetURL undeclared" - although I imported MPMediaItem.h.
In the apple doc it says:
MPMediaItemPropertyAssetURL
A URL pointing to the media item, from which an AVAsset object (or other URL-based AV Foundation object) can be created, with any options as desired. Value is an NSURL object.
The URL has the custom scheme of ipod-library. For example, a URL might look like this:
ipod-library://item/item.m4a?id=12345
Usage of the URL outside of the AV Foundation framework is not supported.
Available in iPhone OS 4.0 and later.
Declared in MPMediaItem.h
Does that mean, it is not possible to access the audio files for own use?
Is there a workaround?
Many thanks

I learned that there is NO way of doing this. As I wrote in the comment - just use MPMediaItemPropertyPersistentID.....

This is an old thread but you can copy a MPMediaItem. You need to use AVAssetExportSession though and not NSFileManager

You should be able to use AVURLAsset, and pass in that URL to the initializer.

Related

openURL a local file or force UIDocumentInteractionController to use a specific app

I wish to open a file (stored locally in my app) with another app.
Currently, I am using openURL (there is a dedicated url scheme), and it works fine if I use a file hosted on the internet, but I would like to use a local file so:
a) it works offline
b) a lot of the time my users are either out of cell zone coverage, or roaming internationally
What I have tried so far:
I have not had any luck telling openURL to use a local file, I have tried a few approaches but they are all something like this
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"test" ofType:#"ext"];
NSURL *fileURL = [NSURL fileURLWithPath:filePath];
[[UIApplication sharedApplication] openURL:fileURL];
also
NSURL *fileURL = [[NSBundle mainBundle] URLForResource: #"test" withExtension:#"ext"];
[[UIApplication sharedApplication] openURL:fileURL];
also manually using strings with different variations of localhost/ and file:// and var/mobile etc paths
nothing works (for me anyway)
So, I looked around SO and came across UIDocumentInteractionController
I am able to use UIDocumentInteractionController to let the user open my local file with the other app - however it always present multiple options of other apps to use and for example, one of the other apps can be 'Dropbox'.
I do not want to let the user download (or upload technically) a copy of my file for their use in other ways. It contains data that I would prefer not to make so readily available.
When the file is opened by my intended app (not made by me btw) it does not allow any kind of saving or access to raw data.
I realize that by including the file in my app anyone who is serious about obtaining it will be able to, I just don't want to flash a big menu saying 'Here it is if you want your own copy to make derivative work from'
Ideally, I could use openURL but I think it is because of the 'sandbox' that the other app doesn't respond - in Android I use mode_world_readable to declare the file as readable by other apps (therefore placing it outside the sandbox, and it doesn't allow other apps to write to it, just read) - is there anyway of doing the same with iOS?
Otherwise, if I could force UIDocumentInteractionController to use a specific app and not present the menu - that would be fine too.
Similar question asked a while ago
Sorry about the long read, any help is appreciated.
Edit:
I just received an answer from Apple Tech support and they told me that this is currently impossible (just after iOS 6 released)
Yes, you're limited because of the strict sandboxing on iOS. Here are some thoughts.
You can override the functionality of the UIDocumentInteractionController by instead subclassing QLPreviewController. You can then replace the standard bar button item that displays the "Open in" menu. Take a look at this post for one solution for subclassing QLPreviewController: QLPreviewController remove or add UIBarButtonItems
Of course, I believe the way inter-app sharing works is largely out of your hands. If an app has registered to be able to handle a certain type of file, it is going to display as one of the choices in the "open in" list whether you want it to or not. I don't believe you can filter which apps display in that list.
Here are two experimental ideas I've thought about but have never tried:
You could base64 encode the data from the file you're trying to pass along--which just converts binary to text--and hand that off as part of the custom URL you use to launch the other app. Then the other app can base64 decode that same data back into binary. The down side there is that there is a limit to the length of the URL which means the "file" you're sending would have to be pretty small.
Next, and I don't even know if this is possible, but I wonder if you could use some steganograhpy algorithm to embed the document data inside an image and then hand that off to the camera roll. Then, the other app could open the camera roll and decode the image back into the data again. ... Yeah. I know... obscure, but it might be fun to try to implement. ;-)
Not sure if any of that helps, but you did say "any help is appreciated". ;-)
Best regards.

iphone update some files in application

I'm creating one iphone application that uses and xml to get some data from and a few images. Lets say that originally these files will be in the application bundle. But then I want to make my application to get updates from a web service. So lets say I download a new xml and new Images.
Where do I save them? I think I will be able to save them in the application "cache" right?
But then How do I make my application check if this resource exists in the cache, then load that one...else load the one in the application bundle?
iOS to be used 4.3 but if it makes it easier we can go to 5.
You will have to use NSFileManager to save the file to and load it from the document directory. Check out the following link, which actually contains all the info you need:
http://www.friendlydeveloper.com/2010/02/using-nsfilemanager-to-save-an-image-to-or-loadremove-an-image-from-documents-directory-coding/
If [UIImage imageWithContentsOfFile:fullPath]; (fullPath being the NSString with contains the path to your image in your document directory) returns nil, then the image is not present, so you'll have to load the default image from your bundle.
You can access your default bundle files using [[NSBundle mainbundle] pathForResource:#"yourFileNameHere" ofType:#"yourTypeHere"] This will return the path to your file in your bundle and you can just pass it to [UIImage imageWithContentsOfFile:]
This example only applies to UIImage, but you can easily adapt it to use other classes. I think the UIImage example is enough for illustrative purposes though.
You'll probably want to create a versioning scheme. After the app starts (or periodically) call the web service for a very cheap call to ask what version it has. You'll know what version you have (write in a plist or have the version number in the folder structure). Another options is pushing a notification.
The next thing you'll have to think about is how the app reacts to getting a new data set. You could do it only on start up but that might block the start up experience if you're bounding it to a web call. The other option is to allow the dataset to change while the app is open. You could have a model that uses NSNotificationCenter to notify your views and controllers that the data has changed. I would probably version the storage as well (folder per) to help with the transition.
As for how, you can make web requests with something like ASIHttpRequest, NSFileManager to write to the documents directory, and plists to save settings like version.

How to get Absolute path for a video using ALAssets Library?

Its simple, How can i get an absolute path for a video retrieved using ALAssets Library? I want to upload this video as file attachment using ASI framework.
It works if i use UIImagePickerViewController. But thats NOT an option any more. I also dont want to use NSData or copy-pasting video to temp file. Need a smart solution? Anybody ?
You can't get the absolute path (file system path) for a video you retrieved using the AssetsLibrary-Framework. The simple reason for that is that these files are outside your app's sandbox and you can't access them directly. You need to use the getBytes-Method of ALAssetsRepresentation to get the byte data of the video file. Most likely you will have to save this data to a temp file, before you can attach it to an email.
Cheers,
Hendrik
You can use ALAssetPropertyAssetURL. From documentation:
The key to retrieve a URL identifier for the asset.
The corresponding value is an NSURL object.
This URL is used by the library-change notifications to identify assets and asset groups. Only the ALAssetRepresentation and ALAssetsGroup classes support this property.
So, once you get ALAsset object you can get url like this:
asset.defaultRepresentation.url

Select a file on an iPhone

I want the user to select a file from an iPhone and upload to an HTTP server.
Example: The GoodReader application has this feature in it.
How can this be done?
You can't get all the files stored on the phone.
As the comment from Stephen Darlington states, your app is sandboxed and can only get to the files stored inside your app.
You could register your app to be able to open PDF, txt, doc and other files that you are interested in sending to your server and then users would be able to open these documents in your app. Once the files are inside your app you could then use any number of ways to upload them.
Please read the documentation here about registering your app to understand file types:
Registering the File Types Your App Supports
The file list would just be a UITableView, probably with a custom UITableViewCell.
There are a number of options for uploading data to a web service. The built-in way would be to use NSURLConnection. There are some open source frameworks that may be able to help but I have not used them.
The best way that I've found to upload images is to use the ASIHTTPRequest API. Here is a link on the documentation on POSTING data to a server. Download ASIHTTPRequest here and these are the setup instructions.
How to select a file depends on what kind of file you're trying to select. If you're trying to upload images you should look into a UIImagePickerController and UIImagePickerControllerDelegate. If not, you'll have to create a NSFileManager to search through your application's files.
NSFileManager Class reference:
http://developer.apple.com/iphone/library/documentation/cocoa/reference/foundation/Classes/NSFileManager_Class/Reference/Reference.html
Discovering Directory Contents:
– mountedVolumeURLsIncludingResourceValuesForKeys:options:
– contentsOfDirectoryAtURL:includingPropertiesForKeys:options:error:
– contentsOfDirectoryAtPath:error:
– enumeratorAtPath:
– enumeratorAtURL:includingPropertiesForKeys:options:errorHandler:
– subpathsAtPath:
– subpathsOfDirectoryAtPath:error:

Streaming and playing an MP3 stream. .mp3 URL format

I used the sample code from http://cocoawithlove.com/2008/09/streaming-and-playing-live-mp3-stream.html. it runs OK with default URL. But when I replace with my URL "http://dl.mp3.kapsule.info/fsfsdfdsfdserwrwq3/fc90613208cc3f16ae6d6ba05d21880c/4b5244f0/b/7e/b7e80afa18d06fdd3dd9f9fa44b51fc0.mp3?filename=Every-Day-I-Love-You.mp3", this app shows an message as "Audio not Found". But when I put my URL on Address Bar of Web Browser, I can download this .mp3 file.
really, I can't understand why it is?
pleased tell me!
Thank you very much
My guess would be that the app is designed to play a MP3 encoded audio stream with no limit in length (which is different from your ordinary music file). To set this up, you need a streaming server on the client side.
I think you can find out for sure by trying with a different radio station that transmits in MP3. If that works, it's most likely that your app doesn't like your file.
You should, as Vivek recommends, also try using a simpler download URL for your file, in case the App gets confused by the URL's length and/or structure.
As mentioned, this is due to the URL of the file. The AudioStreamer code specifically checks for the extension of the file and tries to figure out the audio type based on that. If you change that logic to handle your custom URLs, it will start working
So to point you in the right direction: open AudioStreamer.m and look for the references of
hintForFileExtension:
This function returns the type of file based on the extension. If you know the file type won't change (always mp3), the quick and dirty solution is to always assign mp3 type without any logic... like this:
err = AudioFileStreamOpen(self, MyPropertyListenerProc, MyPacketsProc, kAudioFileMP3Type, &audioFileStream);
Note: I've put kAudioFileMP3Type constant instead of calculated value
PS yes, it does work with static mp3 files, even though it's designed for streams and hence misses some of the functionality one would expect from a player that plays a static file on the server (caching, prefetching, proper seeking)
Thats because the default url directly points to a file in the webserver, whereas the the url you've mentioned is a HTTP (POST/GET) operation, which the application may not be designed to handle.
I suspect that your URL is one-time-use. When I try to visit it, I see 408 - Request Timeout.
Many links on mass file sharing websites are like this. If you could download the file directly, you wouldn't sit through a page of ads and premium account offers.
Try again with a file on a normal website, like this one.