I'm using the Alamofire API to download content in my iOS project. It works great but I only want to download audio content and store it to my file directory as an mp3. Mp3 files download fine, but some audio content exists that I want to download and have no path extension. Audi content with no extension gets downloaded and can still be played from my AVAudioPlayer(), but I need to convert these files into mp3 as well.
Is there a way to convert these audio files with no extension to mp3? I tried simply adding the ".mp3" path extension, but I don't think it's that simple. Any help would be greatly appreciated.
// Download Destination
let dest: DownloadRequest.DownloadFileDestination = { _, _ in
let documentsURL:NSURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! as NSURL
print("***documentURL: ",documentsURL)
let fileURL = documentsURL.appendingPathComponent(url.lastPathComponent)
print("***fileURL: ",fileURL ?? "")
return (fileURL!,[.removePreviousFile, .createIntermediateDirectories])
}
// Download Operation
Alamofire.download(url, to: dest)
.downloadProgress(closure: {(progress) in
print("Progress: \(progress.fractionCompleted)")
self.appDelegate.downloadProgressQueue[url] = Float(progress.fractionCompleted)
}).validate(contentType: ["audio/mpeg"])
.response(completionHandler: {(complete) in
if complete.error == nil, let filePath = complete.destinationURL?.path {
// Download Completed
}
else {
// Download Unsuccessful
}
})
adding the ".mp3" path extension
won't change file format.
You should convert your audio file. BUT you can't create .mp3 file on iOS Device.
Related
I'm basically trying to save an audio file to an iPhone device, specifically in the Files app.
This is the code I'm using which works in the iOS Simulator:
if let audioUrl = URL(string: "https://file-examples.com/wp-content/uploads/2017/11/file_example_MP3_700KB.mp3") {
// 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", destinationUrl)
// if the file doesn't exist
} else {
// you can use NSURLSession.sharedSession to download the data asynchronously
URLSession.shared.downloadTask(with: audioUrl) { location, response, error 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)
print("File moved to documents folder", destinationUrl)
} catch {
print(error)
}
}.resume()
}
}
this is the result in the simulator:
2022-04-08 15:48:17.605964+0200 TunnelPlay[3977:122650] [boringssl] boringssl_metrics_log_metric_block_invoke(153) Failed to log metrics
File moved to documents folder file:///Users/panashemuzamhindo/Library/Developer/CoreSimulator/Devices/A7F7DD88-1E0C-45CD-9783-F46E6644F98C/data/Containers/Data/Application/EDE8B3CC-C290-4369-8B88-4AE1717B9DB8/Documents/1645329769Sengkhathele(featit.caramel).mp3
Main Problem: When I try run this section in TestFlight, the app runs the save process but theres nothing in Files, maybe I'm looking for it in the wrong location? or I need some permissions?
Desired Outcome: I want to see the downloaded MP3 in the iPhone Files app.
And I did try to change the scheme to Release instead of Debug, but it still doesn't save the file.
If you want to be able to access the files in the iOS Files app, make sure to also enable LSSupportsOpeningDocumentsInPlace (in addition to enabling UIFileSharingEnabled)
LSSupportsOpeningDocumentsInPlace
A Boolean value indicating whether the app may open the original document from a file provider, rather than a copy of the document.
UIFileSharingEnabled
A Boolean value indicating whether the app shares files.
I have downloaded a pdf using code below. I am able to find the file in App Data Container, but from app data container my device needs Mac, x code or iTunes etc.
Can I give a distinction path to Documents OR another place to find the pdf in iPhone files? I have an option to open the file with iBook but it is not there.
My code to download the file is here:
func downloadFile(){
let url = "https://www.tutorialspoint.com/swift/swift_tutorial.pdf"
let fileName = "MyFile"
savePdf(urlString: url, fileName: fileName)
}
func savePdf(urlString:String, fileName:String) {
DispatchQueue.main.async {
let url = URL(string: urlString)
let pdfData = try? Data.init(contentsOf: url!)
let resourceDocPath = (FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)).last! as URL
let pdfNameFromUrl = "YourAppName-\(fileName).pdf"
let actualPath = resourceDocPath.appendingPathComponent(pdfNameFromUrl)
do {
try pdfData?.write(to: actualPath, options: .atomic)
print("pdf successfully saved!")
//file is downloaded in app data container, I can find file from x code > devices > MyApp > download Container >This container has the file
} catch {
print("Pdf could not be saved")
}
}
}
Configure your app so that its files appear in the Files app by adding below lines to your Info.plist file.
<key>UIFileSharingEnabled</key>
<true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
OR
Just like below using Xcode
Note: Remember that you must be running iOS 11 or above.
hope you are doing good in development. I have a question regarding Zipping currently i am using Zip framework which I am using for zip the all captured image in device but the problem here is I do not want to save the Zip file in document directory instead I wanna save this memory itself. I am struggling since last week please let me know how can we achieve the zipping without saving it in local directory filepath
Also when I captured the image successfully I saved it to local directory using
let documentsDirectory = FileManager.default.urls(for:
.documentDirectory, in: .userDomainMask).first!
let fileName = "image.jpg"
let fileURL = documentsDirectory.appendingPathComponent(fileName)
if let data = UIImageJPEGRepresentation(image, 1.0),
!FileManager.default.fileExists(atPath: fileURL.path) {
do {
// writes the image data to disk
try data.write(to: fileURL)
print("file saved")
} catch {
print("error saving file:", error)
}
}
After when I am trying to send the image before our server I want to make it all one file so I have implemented the Zip (framework)
Here filpathArray meant all captured image in local path
do {
var urls = [URL]()
for i in 0..<(self.filePathArray.count)
{
urls.append(self.filePathArray[i] as! URL)
}
if self.filePathArray.count > 0 {
let zipFiles = try Zip.quickZipFiles(urls, fileName: "AllFiles")
}
}
Here zipping is done successfully but it saved in local path so when using app container I can able to see the images, I do not want to see the images in device like apple sandbox or Xcode container itself
I want to make zipping on the flow like without saving it document directory, Thanks in advance.
I'm trying to download a youtube video on the phone so the user can later play it offline. I hooked a button to where the user can download. The code of how I'm currently downloading the video is here below.
#objc func downloadSelectedVideo() {
if let audioUrl = URL(string: "http://freetone.org/ring/stan/iPhone_5-Alarm.mp3") {
// create your document folder url
let documentsUrl = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
// your destination file url
let destination = documentsUrl.appendingPathComponent(audioUrl.lastPathComponent)
print(destination)
// check if it exists before downloading it
if FileManager().fileExists(atPath: destination.path) {
print("The file already exists at path")
} else {
// if the file doesn't exist
// just download the data from your url
URLSession.shared.downloadTask(with: audioUrl, completionHandler: { (location, response, error) in
// after downloading your data you need to save it to your destination url
guard
let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200,
let mimeType = response?.mimeType, mimeType.hasPrefix("audio"),
let location = location, error == nil
else { return }
do {
try FileManager.default.moveItem(at: location, to: destination)
print("file saved")
} catch {
print(error)
}
}).resume()
}
}
}
as you can see I have hooked up the URL to a free music which is in mp3 and it works fine I can download the music and everything works just fine, however when I try to hook up a YouTube video then it never gets to the print statement file saved I tried this as the URL if let audioUrl = URL(string: "https://www.youtube.com/watch?v=3WSgJCYIewM")
but the print statement file saved never ran, but when I tried with the other I mentioned earlier it print file saved.
What URL should use to download the youtube videos, and do I have to use an mp3 or mp4 source to download the videos. I'm trying not to use any third-party sites if you can come up with any solution it would be great and helpful. Thanks
YouTube spells this out pretty specifically that you cannot do this.
YouTube API Services - Developer Policies
Found this under E. Handling YouTube Data and Content
You and your API Clients must not, and must not encourage, enable, or
require others to:
download, import, backup, cache, or store copies of YouTube
audiovisual content without YouTube's prior written approval,
IANAL, but I'd rather not go up against their legal team.
YouTube does not provide a simple URL that taps into the video or audio directly. Instead, you would have to extract thier link using some algorithm. If you'd like to achieve that I would recommend you use XCDYouTubeKit as it is well maintained and easy to use. However, If you'd like a ready made app, I have developed an open source application - YouTag - that you can simply install on your iOS device and use directly without having to go through developing one.
I know that Alamofire (iOS) allows the specification of a download destination, but the file stays in the temp directory until the download is complete. We want to be able to have the file sit in the Documents Directory during this process (and have the download remain there once it's complete).
Does anyone know if this is possible?
Thanks
I wasn't able to accomplish this with download tasks. Alamofire essentially wraps URLSession, and Alamofire.download wraps URLSessionDownloadTask, and I'd already tried using this outside of Alamofire. The file isn't placed in your download destination until it's complete.
To accomplish this for now, I've had to use a URLSessionDataTask, and write the data chunk by chunk to a file using am OutputStream/NSOutputStream that is opened and closed repeatedly, so that it gets flushed, and can be read before it is complete. That's what I was trying to accomplish, and it appears to work, and work more than fast enough.
Yes, specify the download location URL
let destination: DownloadRequest.DownloadFileDestination = { _, _ in
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let fileURL = documentsURL.appendPathComponent("pig.png")
return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
}
Alamofire.download(urlString, to: destination).response { response in
print(response)
if response.result.isSuccess, let imagePath = response.destinationURL?.path {
let image = UIImage(contentsOfFile: imagePath)
}
}
Change the document directory Path as you require.