Hey guys, today we are going to explore how can we import local music from your iPhone or iPad’s file app into your iOS application.
Many times, as a developer we come across requirements where we want to add some music from your local music library instead of getting it from API.
So, in this scenario, we will use `UIDocumentPickerViewController` which is used to open the file manager app.
First, let’s talk about UIDocumentPickerViewController
. It’s a view controller that provides access to documents or destinations outside your app’s sandbox.
By adding this media-picker view controller, your app allows users to choose music items from their Apple Music library without leaving your app. You can configure the media picker to accept single or multiple items from the user.
First, let’s create a project and design a simple view for the basic scenario, and using that view we can directly open our apple file app to pick the music.
Initially, we will add a simple button to open the picker view.
@IBAction func onAddButtonClick(_ sender: UIButton) {
var documentPicker: UIDocumentPickerViewController
if #available(iOS 14.0, *) {
let supportedTypes: [UTType] = [UTType.audio]
documentPicker = UIDocumentPickerViewController(forOpeningContentTypes: supportedTypes)
} else {
documentPicker = UIDocumentPickerViewController(documentTypes: ["public.audio"], in: UIDocumentPickerMode.import)
}
documentPicker.delegate = self
self.present(documentPicker, animated: true, completion: nil)
}
Looks like something messy but it’s pretty simple actually.
On click of the add button, the code will open the picker as shown below.
However, on iPad, you can not directly present this picker. For that, you will have to use UIPopoverPresentationController
as shown below.
if let popoverController = documentPicker.popoverController {
popoverPresentationController.sourceView = yourParentView
}
Add this code after setting the delegate.
Now, note that we need to provide supporting music types to the picker as we have music with many mime types like MP3, AAC, ALAC, M4A, WAV, AIFF, etc.
But the good thing is that we have a common type that allows all the mime types — named .audio
and that’s what we have used in the example code.
Now if you click on the add button, it will open the file app and will show all the music located on your phone. Now you can pick any music from these and do whatever you want with it as it provides a URL of that picked music.
Here is the implementation of the delegate method.
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
guard let url = urls.first else { return }
let asset = AVURLAsset(url: url)
guard asset.isComposable else {
print("Your music is Not Composible")
return
}
addAudio(audioUrl: url)
}
func addAudio(audioUrl: URL) {
// then lets create your document folder url
let documentsDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
// lets create your destination file url
let destinationUrl = documentsDirectoryURL.appendingPathComponent(audioUrl.lastPathComponent)
print(destinationUrl)
// to check if it exists before downloading it
if FileManager.default.fileExists(atPath: destinationUrl.path) {
print("The file already exists at path")
self.playMusic(url: destinationUrl)
} else {
// if the file doesn't exist you can use NSURLSession.sharedSession to download the data asynchronously
URLSession.shared.downloadTask(with: audioUrl, completionHandler: { (location, response, error) -> Void in
guard let location = location, error == nil else { return }
do {
// after downloading your file you need to move it to your destination url
try FileManager.default.moveItem(at: location, to: destinationUrl)
self.playMusic(url: destinationUrl)
print("File moved to documents folder")
} catch let error as NSError {
print(error.localizedDescription)
}
}).resume()
}
}
UIDocumentPickerViewController
provides a delegate method didPickDocumentAt
using which we can get the URL of the selected music.
From that URL, we can download the music in our app and we can store it into our app’s directory according to the requirements.
You can also play that music by using the playMusic
function as we have shown.
In case you are wondering, here is the implementation of this playMusic
function.
func playMusic(url: URL) {
do {
audioPlayer = try AVAudioPlayer(contentsOf: url)
audioPlayer.prepareToPlay()
audioPlayer.play()
} catch let error {
print(error.localizedDescription)
}
}
It’s pretty simple, isn’t it?
So that’s it, hope you learned something useful !!!
Whether you need...