iOS dev— Import Music from the User’s Device Using a Document Picker

Import the device's audio easily with Swift in your iOS app
Dec 23 2021 · 3 min read

Introduction

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.

Get Started!

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.

Show Media Picker

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.

Play Imported Media

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 !!!


amisha-i image
Amisha Italiya
iOS developer @canopas | Sharing knowledge of iOS development


amisha-i image
Amisha Italiya
iOS developer @canopas | Sharing knowledge of iOS development

Whether you need...

  • *
    High-performing mobile apps
  • *
    Bulletproof cloud solutions
  • *
    Custom solutions for your business.
Bring us your toughest challenge and we'll show you the path to a sleek solution.
Talk To Our Experts
footer
Subscribe Here!
Follow us on
2024 Canopas Software LLP. All rights reserved.