I have a download function working perfectly, on click of my button, the file is being download correctly.
What I am trying to achieve, If I put the App in the background or change screen while it's downloading the file, I'd like the download to be continued. Currently if the App is in the background ,the download stop and user need to restart it from zero.
How is this possible to make ?? Below is my download function, I tried to add a background download without success.
func createDownloadTask() {
let downloadRequest = URLRequest(url: URL(string: "\(posts[selectedIndexPath].link)")!)
let session = Foundation.URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: OperationQueue.main)
downloadTask = session.downloadTask(with: downloadRequest)
downloadTask!.resume()
}
and
#IBAction func startDownload(_ sender: UIButton) {
let urlString = "\(posts[selectedIndexPath].link)"
DispatchQueue.global(qos: .default).async(execute: {
print("downloadVideo");
let url=NSURL(string: urlString);
let urlData=NSData(contentsOf: url! as URL);
if((urlData) != nil)
{
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let fileName = urlString as NSString;
let filePath="\(documentsPath)/\(fileName.lastPathComponent)";
DispatchQueue.main.async(execute: { () -> Void in
print(filePath)
urlData?.write(toFile: filePath, atomically: true);
print("video Saved to document directory of app");
self.downloadButton.alpha = 0;
self.progressView.alpha = 0;
self.cardboardButton.alpha = 1;
self.videoButton.alpha = 1;
self.removefile.alpha = 1;
})
}
})
}
You need to use UIBackgroundTaskIdentifier. You can start some task in background with beginBackgroundTask see:
https://developer.apple.com/reference/uikit/uiapplication/1623031-beginbackgroundtask.
System will give you some time and you can finish your task. If the time expire you will receive handler.See example that I use to upload a image
static var backgroundUpload:UIBackgroundTaskIdentifier?
static func praiseCollegue(praiseCollegueId:Int,image:UIImageView,praisedBy:Int,praiseText:String,praiseCategory:Int,successBlock: (()->())?,errorBlock: (()->())?){
backgroundUpload = UIApplication.shared.beginBackgroundTask(expirationHandler: {
if let task = self.backgroundUpload{
UIApplication.shared.endBackgroundTask(task)
}
})
let url = NSURL(string: "someUrl")
let request = NSMutableURLRequest(url: url! as URL)
request.httpMethod = "POST"
request.setValue(InfoManager.sharedInstance.tokenInfo?.accessToken, forHTTPHeaderField: "AccessToken")
let session = URLSession.shared
let task = session.dataTask(with: request as URLRequest) {
(
data, response, error) in
if let responseData = data{
do {
if let dict = try JSONSerialization.jsonObject(with: responseData, options: []) as? [String: AnyObject]{
if let errorCode = dict["errorCode"] as? Int{
if(errorCode == 1){
successBlock?()
if let task = self.backgroundUpload{
UIApplication.shared.endBackgroundTask(task)
}
}
else{
errorBlock?()
if let task = self.backgroundUpload{
UIApplication.shared.endBackgroundTask(task)
}
}
}
}
}
}
}
task.resume()
}
Related
I've created a streaming video app that also downloads videos locally. How can I display downloaded videos in the iPhone/iPad Storage sections of settings?
I'm downloading using background tasks, and on complete running
let docsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let destinationUrl = docsUrl.appendingPathComponent(videoId + ".mp4")
let fileManager = FileManager.default
try? fileManager.removeItem(at: destinationUrl)
do {
try fileManager.copyItem(at: location, to: destinationUrl)
} catch let error {
print("Could not copy file to disk: \(error.localizedDescription)")
return
}
Apps like Netflix, Disney+ and Prime Video all show the downloaded shows and allow them to be deleted individually, but I haven't been able to figure out how it's done. All searches usually lead to guides for users on how to delete videos.
Anybody have any tips?
This code is working for me:
func downloadVideo1(videoString :String)
{
let myStringArr = videoString.components(separatedBy: "/")
let finalString = myStringArr[myStringArr.count - 1]
let session = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: OperationQueue.main)
let docsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let destinationUrl = docsUrl.appendingPathComponent(finalString)
if(FileManager().fileExists(atPath: destinationUrl.path)){
print("\n\nfile already exists\n\n")
}
else{
// setupProgress()
//DispatchQueue.global(qos: .background).async {
var request = URLRequest(url: URL(string: videoString)!)
request.httpMethod = "GET"
_ = session.dataTask(with: request, completionHandler: { (data, response, error) in
if(error != nil){
print("\n\nsome error occured\n\n")
return
}
if let response = response as? HTTPURLResponse{
if response.statusCode == 200{
DispatchQueue.main.async {
if let data = data{
if let _ = try? data.write(to: destinationUrl, options: Data.WritingOptions.atomic){
print("\n\nurl data written\n\n")
print(destinationUrl)
self.checkCount = self.checkCount + 1
if self.checkCount == self.availableMediaCount
{
self.progressView.isHidden = true
let vc = TeacherLessonPlanSB.instantiateViewController(withIdentifier: "DownloadLessonVC") as! DownloadLessonViewController
self.navigationController?.pushViewController(vc, animated: true)
}
}
else{
print("\n\nerror again\n\n")
}
}//end if let data
}//end dispatch main
}//end if let response.status
}
}).resume()
}
}
I am making small music player with mp3 ftp steam.
It's how i add my URL's to list:
self.playList.add("http://my-ftp.pl/mp3/1.mp3")
self.playList.add("http://my-ftp.pl/mp3/2.mp3")
self.playList.add("http://my-ftp.pl/mp3/3.mp3")
...
self.play(url: URL(string:(playList[self.index] as! String))!)
I am searching for any ideas how to get all (*.mp3) URL (http://my-ftp.pl/mp3) folder elements without entering the entire path.
There is no way to get contents of a remote folder , but you can
var counter = 1
func getMp3(_ url:URL) {
API.load(url) { (response,data,error) in
if let data = data {
// use data
coounter += 1
getMp3(urlWithNewCounter)
}
}
Sorry guys, but i made that.
func getMp3() {
let url = URL(string: "http://not-my-ftp-just-simple.com/mp3")!
let task = URLSession.shared.downloadTask(with: url) { localURL, urlResponse, error in
if let localURL = localURL {
if let string = try? String(contentsOf: localURL) {
let regex = try! NSRegularExpression(pattern:"href=(.*?)>", options: [])
var results = [String]()
regex.enumerateMatches(in: string, options: [], range: NSMakeRange(0, string.utf16.count)) { result, flags, stop in
if let r = result?.range(at: 1), let range = Range(r, in: string) {
if (String(String(string[range]).toLengthOf(length: 1).dropLast())).contains(".mp3"){
results.append(String(String(string[range]).toLengthOf(length: 1).dropLast()))
}
}
}
print(results)
}
}
}
task.resume()
}
i am storing my data in file manager in my app. now i want to delete specific data by code so how can i do this?
here is my code which i used for store data
var localURL : String
init()
{
let urls = fileManager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
localURL = urls.first!.URLByAppendingPathComponent("podcasts").path!
createDirectory(localURL)
}
func downloadShow(slug: String, show: NSDictionary) {
SVProgressHUD.showWithStatus("Downloading...")
let sessionConfig = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: sessionConfig, delegate: nil, delegateQueue: nil)
let url = NSURL(string: show["file"] as! String)
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "GET"
let task = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
if (error == nil) {
let showFileName = url?.lastPathComponent
let programMP3Path = self.localURL + "/" + slug + "/" + showFileName!
let programDataPath = programMP3Path + ".dat"
data?.writeToFile(programMP3Path, atomically: true)
show.writeToFile(programDataPath, atomically: true)
print("Success")
print(showFileName)
SVProgressHUD.dismiss()
}
else {
// Failure
print("Faulure: \(error)");
}
})
task.resume()
}}
Not sure about session methods. Here's how to delete file in user temp directory, if that helps
let myFileName = "myFile.txt"
var fileManager = NSFileManager()
var tempDirectory = NSTemporaryDirectory()
let filePath = tempDirectory.stringByAppendingPathComponent(myFileName)
var error: NSError?
// also good idea to check before if the file is in the directory
let path = tmpDir.stringByAppendingPathComponent(isFileInDir)
fileManager.removeItemAtPath(path, error: &error)
hi in my app i am storing some data.
here is my code for downloading data
func downloadShow(slug: String, show: NSDictionary) {
SVProgressHUD.showWithStatus("Downloading...")
let sessionConfig = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: sessionConfig, delegate: nil, delegateQueue: nil)
let url = NSURL(string: show["file"] as! String)
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "GET"
let task = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
if (error == nil) {
let showFileName = url?.lastPathComponent
let programMP3Path = self.localURL + "/" + slug + "/" + showFileName!
let programDataPath = programMP3Path + ".dat"
data?.writeToFile(programMP3Path, atomically: true)
show.writeToFile(programDataPath, atomically: true)
print("Success")
SVProgressHUD.dismiss()
}
else {
// Failure
print("Faulure: \(error)");
}
})
task.resume()
}
now i want to clear that particular data on the click of delete button. so how can i delete that data?
this is the path where i stored my data
/var/mobile/Containers/Data/Application/57EDF9A1-1108-4BA9-AE0A-57B8BA61869A/Documents/
you can use removeItemAtURL
let fileManager = NSFileManager.defaultManager()
let enumerator = fileManager.enumeratorAtURL(urlDir, includingPropertiesForKeys: nil, options: nil, errorHandler: nil)
while let file = enumerator?.nextObject() as? String {
fileManager.removeItemAtURL(urlDir.URLByAppendingPathComponent(file), error: nil)
}
Use file Manager to delete your file, I've added obj-c Code,
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
BOOL success = [fileManager removeItemAtPath:YourFilePath error:&error];
I have allready implemented a download session, now what i wanna do is make it to download only a portion of that file. i know that its possible through the byte-range but im not sure how do i have to do that in swift. any help would be much appreciated. thanks.
#IBAction func btnStartDownload(sender: NSButton) {
let downloadUrl = NSURL(string:"http://www.joomlaworks.net/images/demos/galleries/abstract/7.jpg")
let sessionConfiguration:NSURLSessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration()
let session:NSURLSession = NSURLSession(configuration: sessionConfiguration)
let sessionDownloadTask:NSURLSessionDownloadTask = session.downloadTaskWithURL(downloadUrl!, completionHandler: { (data, response, error) -> Void in
let data = NSData(contentsOfURL: data)
var fileManager:NSFileManager = NSFileManager.defaultManager()
var paths:NSArray = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
var documentsDirectory:NSString = paths[0] as NSString
var databasePath:NSString = documentsDirectory.stringByAppendingString("/\(response.suggestedFilename!)")
fileManager.createFileAtPath(databasePath, contents: data , attributes: nil)
NSLog("Database copied to\(databasePath)")
})
sessionDownloadTask.resume()
}