草庐IT

iphone - 在 Swift 后台下载

coder 2023-09-09 原文

我正在尝试让我的应用程序在后台下载图像。但是当我按下 [主页] 按钮时,应用程序停止下载。即使我使用其他应用程序,有什么方法可以让它继续下载吗?我看到一些应用程序可以这样做,但我不知道怎么做。

这是我迄今为止尝试过的。

//
//  AppDelegate.swift
//  Swift-TableView-Example
//
//  Created by Bilal ARSLAN on 11/10/14.
//  Copyright (c) 2014 Bilal ARSLAN. All rights reserved.
//

import UIKit
import WebKit

protocol DownloadInBackgroundDelegate {
func downloadInBackgroundDidFinish(chapterid:Int, chaptername:String,    storyid:Int, progressPercent:Float)
}

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?
var shareCache = NSURLCache()
var downloadDelegate:DownloadInBackgroundDelegate? = nil

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // Override point for customization after application launch.
    var navigationBarAppearace = UINavigationBar.appearance()

    application.setStatusBarOrientation(UIInterfaceOrientation.PortraitUpsideDown, animated: false)

    self.startDownload()

    return true
}

func application(application: UIApplication,
    didReceiveRemoteNotification userInfo: [NSObject : AnyObject],
    fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {

}

func applicationWillResignActive(application: UIApplication) {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

func applicationDidEnterBackground(application: UIApplication) {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

func applicationWillEnterForeground(application: UIApplication) {
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}

func applicationDidBecomeActive(application: UIApplication) {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    FBAppEvents.activateApp()
}

func applicationWillTerminate(application: UIApplication) {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
}

func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {

}

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {

}

func applicationDidReceiveMemoryWarning(application: UIApplication) {
    NSURLCache.sharedURLCache().removeAllCachedResponses()
}

func application(application: UIApplication, willChangeStatusBarOrientation newStatusBarOrientation: UIInterfaceOrientation, duration: NSTimeInterval) {
    application.windows
}

func startDownload(){
    var filesPath = [String]()
    filesPath.append("https://developer.apple.com/library/ios/documentation/iphone/conceptual/iphoneosprogrammingguide/iphoneappprogrammingguide.pdf")
    filesPath.append("https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/MobileHIG.pdf")
    filesPath.append("https://developer.apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/NetworkingOverview.pdf")
    filesPath.append("https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/AVFoundationPG/AVFoundationPG.pdf")
    filesPath.append("http://manuals.info.apple.com/MANUALS/1000/MA1565/en_US/iphone_user_guide.pdf")

    downloadFiles(0, filesPath: filesPath)
}

func downloadFiles(index: Int, filesPath: [String]) -> Void {
    var imgURL: NSURL = NSURL(string: filesPath[index].stringByTrimmingCharactersInSet(.whitespaceAndNewlineCharacterSet()).stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!)!
    let request: NSURLRequest = NSURLRequest(URL: imgURL)
    NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue(), completionHandler: {(response: NSURLResponse!,data: NSData!,error: NSError!) -> Void in
        var fileCacheName = String(format: "%04d", index)

        dispatch_async(dispatch_get_main_queue(), {
            var fileExt = (data != nil && error == nil) ? Utility.checkImageType(data) : ""

            let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as! String
            let imagePath = paths.stringByAppendingPathComponent("\(fileCacheName).png")

            if data.writeToFile(imagePath, atomically: false)
            {
                println("saved")
            }

            if index < filesPath.count - 1
            {
                var nextIndex:Int = index + 1
                self.downloadFiles(nextIndex, filesPath: filesPath)
            }
        })
    })

}

}

回答

根据下面的评论,我找到了这个帖子:objective c - Proper use of beginBackgroundTaskWithExpirationHandler .我可以用它解决我的问题。

最佳答案

对于图像的下载和存储,我建议您使用一些众所周知的库,而不是自己编写逻辑,例如:

这背后的原因是这些库经过了良好的测试,非常健壮并且主要非常易于用于基本任务。

现在对于后台下载,beginBackgroundTaskWithExpirationHandler: 是专门为此设计的。当你使用它时,你将有更多的时间来执行你需要的任何东西(在这个限制之后,你的应用程序无论如何都会被终止)。

您可以编写以下方法:

func beginBackgroundTask() -> UIBackgroundTaskIdentifier {
    return UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler({})
}

func endBackgroundTask(taskID: UIBackgroundTaskIdentifier) {
    UIApplication.sharedApplication().endBackgroundTask(taskID)
}

当你想使用它时,你只需在开始/完成下载调用时简单地开始/结束任务:

// Start task
let task = self.beginBackgroundTask()

// Do whatever you need
self.someBackgroundTask()

// End task
self.endBackgroundTask(task)

希望对您有所帮助!

关于iphone - 在 Swift 后台下载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31604428/

有关iphone - 在 Swift 后台下载的更多相关文章

  1. ruby - 如何使用 Ruby aws/s3 Gem 生成安全 URL 以从 s3 下载文件 - 2

    我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A

  2. ruby - 安装 Ruby 时遇到问题(无法下载资源 "readline--patch") - 2

    当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub

  3. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

  4. ruby - 如何在 ruby​​ 中运行后台线程? - 2

    我是ruby​​的新手,我认为重新构建一个我用C#编写的简单聊天程序是个好主意。我正在使用Ruby2.0.0MRI(Matz的Ruby实现)。问题是我想在服务器运行时为简单的服务器命令提供I/O。这是从示例中获取的服务器。我添加了使用gets()获取输入的命令方法。我希望此方法在后台作为线程运行,但该线程正在阻塞另一个线程。require'socket'#Getsocketsfromstdlibserver=TCPServer.open(2000)#Sockettolistenonport2000defcommandsx=1whilex==1exitProgram=gets.chomp

  5. ruby - 下载位置 Selenium-webdriver Cucumber Chrome - 2

    我将Cucumber与Ruby结合使用。通过Selenium-Webdriver在Chrome中运行测试时,我想将下载位置更改为测试文件夹而不是用户下载文件夹。我当前的chrome驱动程序是这样设置的:Capybara.default_driver=:seleniumCapybara.register_driver:seleniumdo|app|Capybara::Selenium::Driver.new(app,:browser=>:chrome,desired_capabilities:{'chromeOptions'=>{'args'=>%w{window-size=1920,1

  6. ruby-on-rails - HTTParty 的内存问题和下载大文件 - 2

    这会导致Ruby出现内存问题吗?我知道如果大小超过10KB,Open-URI会写入TempFile。但是HTTParty会在写入TempFile之前尝试将整个PDF保存到内存吗?src=Tempfile.new("file.pdf")src.binmodesrc.writeHTTParty.get("large_file.pdf").parsed_response 最佳答案 您可以使用Net::HTTP。参见thedocumentation(特别是标题为“流媒体响应机构”的部分)。这是文档中的示例:uri=URI('http://e

  7. ruby - 强制浏览器下载文件而不是打开文件 - 2

    我要下载http://foobar.com/song.mp3作为song.mp3,而不是让Chrome在其native中打开它浏览器中的播放器。我怎样才能做到这一点? 最佳答案 您只需要确保发送这些header:Content-Disposition:attachment;filename=song.mp3;Content-Type:application/octet-streamContent-Transfer-Encoding:binarysend_file方法为您完成:get'/:file'do|file|file=File.

  8. ruby - 检查网络文件是否存在,而不下载它? - 2

    是否可以在不实际下载文件的情况下检查文件是否存在?我有这么大的(~40mb)文件,例如:http://mirrors.sohu.com/mysql/MySQL-6.0/MySQL-6.0.11-0.glibc23.src.rpm这与ruby​​不严格相关,但如果发件人可以设置内容长度就好了。RestClient.get"http://mirrors.sohu.com/mysql/MySQL-6.0/MySQL-6.0.11-0.glibc23.src.rpm",headers:{"Content-Length"=>100} 最佳答案

  9. ruby-on-rails - Rubygems - 包在哪里下载? - 2

    当你安装一个新包时,例如,'geminstallfb-graph',文件下载到哪里了? 最佳答案 使用此命令查找特定gem的安装位置:gemwhich例如:gemwhichfb-graph 关于ruby-on-rails-Rubygems-包在哪里下载?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/13200065/

  10. ruby - 从谷歌开发者网站下载后,client_secret.json 为空 - 2

    我正在尝试从googleAPI下载client_secret.json。我正在执行https://developers.google.com/gmail/api/quickstart/ruby中列出的步骤.使用此向导在GoogleDevelopersConsole中创建或选择项目并自动启用API。在左侧边栏中,选择同意屏幕。选择电子邮件地址并输入产品名称(如果尚未设置),然后单击“保存”按钮。在左侧边栏中,选择凭据并点击创建新客户端ID。选择应用程序类型已安装应用程序,已安装应用程序类型为其他,然后单击“创建客户端ID”按钮。点击新客户端ID下的下载JSON按钮。将此文件移动到您的工作

随机推荐