ios 如何使用 Swift 3 使用后台任务?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/45192402/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use background task using Swift 3?
提问by kishor0011
I am new in background tasks. I have a small work that I am fetching tweets and If my app is in background mode then also it should fetch tweets, but I don't know how.
我是后台任务的新手。我有一个小工作,我正在获取推文,如果我的应用程序处于后台模式,那么它也应该获取推文,但我不知道如何。
I am using simply Timer in Appdelegate didFinishLaunchOption Method. When I will close the app then it's not working. I am new in that so please any suggestion. Here below is my code:
我在 Appdelegate didFinishLaunchOption 方法中仅使用 Timer 。当我关闭应用程序时,它不起作用。我是新手,所以请提出任何建议。下面是我的代码:
Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(getTweets), userInfo: nil, repeats: true).
func getTweets() {
let locationName = Helper.sharedInstance.userDefault.value(forKey: ModelKey.currentLocation) as? String
let accessToken = Helper.sharedInstance.userDefault.value(forKey: ModelKey.twitterAccessToken) as? String
if (locationName == "Bengaluru" && nil != accessToken) || (locationName == "Bangalore" && nil != accessToken){
tweetModel.getTweets(accessToken: accessToken!, city: ModelKey.blrcitytraffic, cityName: "Bengaluru")
}
}
Text to speech is also there but when I will close the app then it stops speaking. If I am not using app then also it can fetch tweets and text to speech should work using a background mode. How long does that work?
文本到语音也有,但当我关闭应用程序时,它就会停止说话。如果我不使用应用程序,那么它也可以使用后台模式获取推文和文本到语音。那能用多久?
回答by Alfredo Luco G
A background task means you need to use background threads. Threads in iOS are too many, but if you want to make only background task, you should use two threads; the main and background thread that their structure is:
后台任务意味着您需要使用后台线程。iOS中的线程太多了,但是如果你只想做后台任务,你应该使用两个线程;主线程和后台线程,它们的结构是:
DispatchQueue.global(qos: .background).async {
//background code
DispatchQueue.main.async {
//your main thread
}
}
So, you firstly initialize the global queue with background mode. This thread can be used for background task and then you must use main thread (only if you want) for doing something when the background task is finished. This can be an option. Another option should be applicationDidEnterBackground
in appDelegate and you can only must put your code in that method.
因此,您首先使用后台模式初始化全局队列。此线程可用于后台任务,然后您必须使用主线程(仅当您需要时)在后台任务完成时执行某些操作。这可以是一种选择。另一个选项应该applicationDidEnterBackground
在 appDelegate 中,您只能将代码放在该方法中。
回答by christian.buggle
You need to do three things:
你需要做三件事:
In your Info.plist add the following entry for key
Required background modes
to allow background network access:Required background modes:
App downloads content from the network
In your AppDelegate add to your applicationDidEnterBackground():
func applicationDidEnterBackground(_ application: UIApplication) { // Fetch no sooner than every (60) seconds which is thrillingly short actually. // Defaults to Infinite if not set. UIApplication.shared.setMinimumBackgroundFetchInterval( 60 ) ) }
Also in AppDelegate implement
func application(application: UIApplication, performFetchWithCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) { var fetchResult: UIBackgroundFetchResult! if doingYourStuffActuallyCreatesNetworkTraffic() { fetchResult = UIBackgroundFetchResult.newData } else if thereWasAnError() { fetchResult = UIBackgroundFetchResult.failed } else { fetchResult = UIBackgroundFetchResult.noData } completionHandler( fetchResult ) return }
在您的 Info.plist 中为 key 添加以下条目
Required background modes
以允许后台网络访问:Required background modes:
App downloads content from the network
在您的 AppDelegate 中添加到您的 applicationDidEnterBackground():
func applicationDidEnterBackground(_ application: UIApplication) { // Fetch no sooner than every (60) seconds which is thrillingly short actually. // Defaults to Infinite if not set. UIApplication.shared.setMinimumBackgroundFetchInterval( 60 ) ) }
也在 AppDelegate 中实现
func application(application: UIApplication, performFetchWithCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) { var fetchResult: UIBackgroundFetchResult! if doingYourStuffActuallyCreatesNetworkTraffic() { fetchResult = UIBackgroundFetchResult.newData } else if thereWasAnError() { fetchResult = UIBackgroundFetchResult.failed } else { fetchResult = UIBackgroundFetchResult.noData } completionHandler( fetchResult ) return }
There are still some pitfalls, e.g. there is no guaranteed maximum fetch interval, and background execution might behave substantially different in XCode/Simulator than on real devices.
仍然存在一些缺陷,例如没有保证的最大获取间隔,并且后台执行在 XCode/Simulator 中的行为可能与在真实设备上的行为大不相同。
You could take a look at this pretty similiar topic:
你可以看看这个非常相似的话题:
performFetchWithCompletionHandler never gets fired