Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios swift 4:从未调用后台提取_Ios_Swift_Notifications_Background_Fetch - Fatal编程技术网

Ios swift 4:从未调用后台提取

Ios swift 4:从未调用后台提取,ios,swift,notifications,background,fetch,Ios,Swift,Notifications,Background,Fetch,我已经在调试->模拟后台抓取中设置了后台抓取,它工作得很好。然而,当它涉及到真正的设备是永远不会被调用!!!我已经等了将近一个星期了,但没有什么新的 这是我的代码和设置 首先:我已经从capabilities选项卡打开了后台获取功能,并检查了它在info.plist中的反映 <key>UIBackgroundModes</key> <array> <string>fetch</string> </array> 第三

我已经在调试->模拟后台抓取中设置了后台抓取,它工作得很好。然而,当它涉及到真正的设备是永远不会被调用!!!我已经等了将近一个星期了,但没有什么新的

这是我的代码和设置 首先:我已经从capabilities选项卡打开了后台获取功能,并检查了它在info.plist中的反映

<key>UIBackgroundModes</key>
<array>
    <string>fetch</string>
</array>
第三:我正在运行在performFetchWithCompletionHandler中调用后台获取时要处理的进程

func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
            let content =  UserNotifications.UNMutableNotificationContent()

    let documentsPath = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
    let destinationSqliteURL = documentsPath.appendingPathComponent("MyDB.db")
    let db = FMDatabase(path: destinationSqliteURL.path)

    if !db.open() {
        print("Unable to open database")
        completionHandler(UIBackgroundFetchResult.failed)
        return
    }
    var title : String!
    if let rs = db.executeQuery("select _Title from Questions ORDER BY RANDOM() LIMIT 1;", withArgumentsIn: []){
        while (rs.next()){
            title = rs.string(forColumn: "_Title")
        }
    } else {
        print("select failed: \(db.lastErrorMessage())")
        completionHandler(UIBackgroundFetchResult.failed)
    }
    content.title = "Q&A of the Day"
    content.body = title!
    content.sound = UNNotificationSound.default()

    var dateComponents = DateComponents()
    dateComponents.calendar = Calendar.current

    dateComponents.hour = 8   // 8:00 hours

    let trigger = UNCalendarNotificationTrigger(
        dateMatching: dateComponents, repeats: true)

    let uuidString = UUID().uuidString
    let request = UNNotificationRequest(identifier: uuidString,
                                        content: content, trigger: trigger)


    let notificationCenter = UNUserNotificationCenter.current()
    notificationCenter.removeAllPendingNotificationRequests()
    notificationCenter.add(request) { (error) in
        if error != nil {
            print("ERROR in setting up the scheduled notification request")
            completionHandler(UIBackgroundFetchResult.failed)
        }
        else{
            print("Notification is Sent")
            completionHandler(UIBackgroundFetchResult.newData)
        }
     }
 }

当从模拟后台获取调试它时,它可以完美地工作,然而,在真实设备上测试它时,它甚至不会被调用一次。我知道,如果它只被调用一次,那么我应该在每天早上8:00发送通知,这在真正的设备上不是这样的。

也许这是沙箱问题。您可能没有权限。iOS不会承诺后台获取的时间,但是它应该至少每周执行一次。也许还有其他因素使iOS推迟/取消应用程序的后台提取。@AliIhsanURAL,如果是沙盒问题,那么为什么它在调试时工作。。。请详细说明。。。谢谢你,我也是这么说的。也许是许可问题。在真实设备中需要一些权限,但在模拟器中不需要。@AliIhsanURAL我已经检查了我正在测试的设备的所有权限,我认为所有权限都满足要求(除非我不知道还需要另一个权限,我会请您为我澄清)。我甚至在设备设置->我的应用程序名称->后台应用程序刷新中检查了后台应用程序刷新是否打开
func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
            let content =  UserNotifications.UNMutableNotificationContent()

    let documentsPath = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
    let destinationSqliteURL = documentsPath.appendingPathComponent("MyDB.db")
    let db = FMDatabase(path: destinationSqliteURL.path)

    if !db.open() {
        print("Unable to open database")
        completionHandler(UIBackgroundFetchResult.failed)
        return
    }
    var title : String!
    if let rs = db.executeQuery("select _Title from Questions ORDER BY RANDOM() LIMIT 1;", withArgumentsIn: []){
        while (rs.next()){
            title = rs.string(forColumn: "_Title")
        }
    } else {
        print("select failed: \(db.lastErrorMessage())")
        completionHandler(UIBackgroundFetchResult.failed)
    }
    content.title = "Q&A of the Day"
    content.body = title!
    content.sound = UNNotificationSound.default()

    var dateComponents = DateComponents()
    dateComponents.calendar = Calendar.current

    dateComponents.hour = 8   // 8:00 hours

    let trigger = UNCalendarNotificationTrigger(
        dateMatching: dateComponents, repeats: true)

    let uuidString = UUID().uuidString
    let request = UNNotificationRequest(identifier: uuidString,
                                        content: content, trigger: trigger)


    let notificationCenter = UNUserNotificationCenter.current()
    notificationCenter.removeAllPendingNotificationRequests()
    notificationCenter.add(request) { (error) in
        if error != nil {
            print("ERROR in setting up the scheduled notification request")
            completionHandler(UIBackgroundFetchResult.failed)
        }
        else{
            print("Notification is Sent")
            completionHandler(UIBackgroundFetchResult.newData)
        }
     }
 }