AppDelegate当我的应用程序进入后台时,我有以下代码:
var backgroundUpdateTask: UIBackgroundTaskIdentifier!
func beginBackgroundUpdateTask() {
self.backgroundUpdateTask = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler({
self.endBackgroundUpdateTask()
})
}
func endBackgroundUpdateTask() {
UIApplication.sharedApplication().endBackgroundTask(self.backgroundUpdateTask)
self.backgroundUpdateTask = UIBackgroundTaskInvalid
}
func doBackgroundTask() {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
self.beginBackgroundUpdateTask()
// Do something with the result.
var timer = NSTimer.scheduledTimerWithTimeInterval(5, target: self, selector: "displayAlert", userInfo: nil, repeats: false)
NSRunLoop.currentRunLoop().addTimer(timer, forMode: NSDefaultRunLoopMode)
NSRunLoop.currentRunLoop().run()
// End the background task.
self.endBackgroundUpdateTask()
})
}
func displayAlert() {
let note = UILocalNotification()
note.alertBody = "As a test I'm hoping this will run in the background every …Run Code Online (Sandbox Code Playgroud) 我在XTubeManager中遇到大量崩溃(似乎是CFNetwork内部).不幸的是,控制台日志不可用,只有调用堆栈(见下文).
NSURLRequests?(见下面的代码)我经常在后台(或通过后台推送)醒来并运行这样的后台任务:
NSString *myTaskName = @"some.random.task.name";
__block UIBackgroundTaskIdentifier taskID = [UIApplication.sharedApplication beginBackgroundTaskWithName:myTaskName expirationHandler:^{
[UIApplication.sharedApplication endBackgroundTask:taskID];
taskID = UIBackgroundTaskInvalid;
}];
dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(q,
// doing some NSURLRequests stuff here
[UIApplication.sharedApplication endBackgroundTask:taskID];
taskID = UIBackgroundTaskInvalid;
});
Run Code Online (Sandbox Code Playgroud)
这通常被称为 applicationDidEnterBackground
Thread : Crashed: com.apple.NSURLConnectionLoader
0 libobjc.A.dylib 0x183599b90 objc_msgSend + 16
1 CFNetwork 0x184513300 XTubeManager::withTubeManager(CoreSchedulingSet const*, void (GlueTubeManager*) block_pointer) + 96
2 CFNetwork 0x18451149c -[__NSURLSessionLocal _withConnectionCache_enqueueRequest:forProtocol:scheduling:options:] + 128
3 CFNetwork 0x1845c3798 HTTPProtocol::asynchronouslyCreateAndOpenStream_WithMessage_AfterCookiesAndAuthenticatorHeaders(__CFHTTPMessage*) + 2000
4 …Run Code Online (Sandbox Code Playgroud) objective-c nsurlconnection nsurlrequest ios uibackgroundtask
即使应用程序在后台进行,我也有一些长时间运行的进程.我正在调用应用程序的beginBackgroundTaskWithExpirationHandler:方法,在expirationBlock中我正在调用应用程序endBackgroundTask.这是实施:
__block UIBackgroundTaskIdentifier task = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:task];
task = UIBackgroundTaskInvalid;
}];
dispatch_queue_t queue = dispatch_queue_create("com.test.test1234", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
// My Task goes here
});
Run Code Online (Sandbox Code Playgroud)
在某些情况下,我的串行队列有更多要执行的任务,这些任务无法在系统提供的时间内完成.因此,到期块将执行,并且我将结束UIBackgroundTaskIdentifier但不停止调度过程(我甚至无法取消调度).
Apple的文件说:
每次调用beginBackgroundTaskWithName:expirationHandler:或beginBackgroundTaskWithExpirationHandler:方法都会生成一个唯一的令牌以与相应的任务相关联.当您的应用程序完成任务时,它必须使用相应的令牌调用endBackgroundTask:方法,以让系统知道任务已完成.未能为后台任务调用endBackgroundTask:方法将导致应用程序终止.如果在启动任务时提供了过期处理程序,系统将调用该处理程序并为您提供最后一次结束任务并避免终止的机会.
所以,根据这个,如果我不打电话,endBackgroundTask:我的应用程序将被终止,这是好的.
我的问题是:对于我当前的实现,如果我调用endBackgroundTask:expirationHandler块并且我的调度队列的任务没有完成,该怎么办?我的应用程序将被终止或将被暂停?
谢谢
当应用程序暂时在后台进入时,我正在尝试维护MultipeerConnectivity"会话",所以我考虑使用后台任务,因为我在这里看过几次......问题是我不知道如何"维护"与UIBackgroundTask的会话,有人可以发一个提示
我不关心广告商/浏览器,可以阻止它们,但是我希望会话不会断开,因为重新连接目前是超级错误.
我正在运行某项任务,UIBackgroundTaskIdentifier因为我想在后台运行它.我的代码看起来像这样.
-(void) function
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
UIBackgroundTaskIdentifier BGIdentifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{}];
// some processing
dispatch_async(dispatch_get_main_queue(), ^{
// some UI stuff
});
// some processing again
dispatch_async(dispatch_get_main_queue(), ^{
// some UI stuff again
});
[[UIApplication sharedApplication] endBackgroundTask:BGIdentifier];
});
}
Run Code Online (Sandbox Code Playgroud)
所以我有两个问题.
objective-c grand-central-dispatch objective-c-blocks uibackgroundtask
我有一个后台任务,应该返回一系列课程,然后将其发送到苹果手表。didReceiveMessage我正在通过调用内部任务WatchConnectivity。
后台任务需要执行一些操作,例如打开领域数据库、查询结果和访问文档目录,然后将响应返回到课程字典。当手表输出其获取的课程数据时,该逻辑似乎有效。问题是我认为后台任务实际上并没有调用该方法getWatchCourses()
DispatchQueue.global().async {
var foundCourses = [[String : Any]]()
let application = UIApplication.shared
backgroundTask = application.beginBackgroundTask(withName: "app.test.getCourses") {
let watchModel = WatchCourseModel()
let courses = watchModel.getWatchCourses()
print("Courses: \(courses)")
foundCourses.append(contentsOf: courses)
}
replyHandler(["response": foundCourses])
application.endBackgroundTask(backgroundTask)
backgroundTask = UIBackgroundTaskInvalid
}
Run Code Online (Sandbox Code Playgroud)
如果结果是硬编码的,这也不起作用getWatchCourses()。应用程序可以在后台执行此逻辑吗?或者它应该工作吗?
还值得指出的是,网上没有任何地方记录了这一点,他们总是指将简单的文本响应发送回手表,而不是处理器密集型的东西:(
谢谢
iOS13不支持后台更新通知。这是操作系统级别的错误吗?当应用进入后台时,Xcode警告显示:
无法结束BackgroundTask:不存在标识符为1(0x1)的后台任务,或者它可能已经结束。中断UIApplicationEndBackgroundTaskError()进行调试。
我遇到一个奇怪的问题,在一个XCode项目中工作的代码无法在另一个项目中编译。两者都运行Swift4.2。
为什么会出现“ UIBackgroundTaskIdentifier没有成员'无效'错误?
导入UIKit导入基金会
//Type 'UIBackgroundTaskIdentifier' (aka 'Int') has no member 'invalid'
var backgroundTask: UIBackgroundTaskIdentifier = UIBackgroundTaskIdentifier.invalid
Run Code Online (Sandbox Code Playgroud)
我正在调试我们的应用程序的用户报告,这些报告在iOS11开始时在后台重复退出,即使在活动使用期间(例如,用户背景我们并在几秒钟或一分钟内返回,只是发现它重新启动).崩溃日志都显示了相同的原因:看门狗超时.以下是一个此类崩溃日志中的相关位:
Exception Type: EXC_CRASH (SIGKILL)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Termination Reason: Namespace <0xF>, Code 0x8badf00d
Triggered by Thread: 0
Run Code Online (Sandbox Code Playgroud)
我意识到我们的代码在接收推送通知或后台运行时的操作时间有限.我们肯定使用UIBackgroundTasks(使用Alamofire Networking,FWIW),我们确实有过期处理程序来执行此操作:
backgroundTask = [application beginBackgroundTaskWithExpirationHandler:^{
[application endBackgroundTask:backgroundTask];
backgroundTask = UIBackgroundTaskInvalid; // Set the task to be invalid
DebugLog(@"Ended because expiration");
}];
Run Code Online (Sandbox Code Playgroud)
关于这些崩溃报告最令人困惑的事情是我们的代码无处于堆栈中.我们可以从Apple对0x8badf00d异常代码的讨论中看到,实际上,有问题的代码正在主线程上主动执行.
但是,在我的情况下,没有任何堆栈有任何代码被执行.这是一个代表性的样本:
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x0000000183208bc4 0x183208000 + 3012
1 libsystem_kernel.dylib 0x0000000183208a3c 0x183208000 + 2620
2 CoreFoundation 0x00000001836b9c4c 0x1835d0000 + 957516
3 CoreFoundation 0x00000001836b7818 …Run Code Online (Sandbox Code Playgroud) 我有一个应用程序,我正在保存数据,但当应用程序在后台被杀死时,我必须删除所有已保存的数据.
我尝试过使用这种方法:
- (void)applicationWillTerminate:(UIApplication *)application
Run Code Online (Sandbox Code Playgroud)
但它不起作用.有人可以建议我怎么做吗?
uibackgroundtask ×10
ios ×6
ios7 ×2
objective-c ×2
swift ×2
ios12 ×1
ios13 ×1
ios6 ×1
ios8 ×1
nsurlrequest ×1
swift4.2 ×1
watchkit ×1
xcode10 ×1
xcode11 ×1