IOS:无法将数据从urlSessionDownloadTask保存到coredata Swift

时间:2018-09-10 09:05:37

标签: ios swift xcode

我想实现以下功能:

我需要在接收到推送通知时使用urlSessionDownloadTask下载文件。收到推送通知后,我开始使用urlSessionBackgroundTask下载文件。该文件已成功下载。 然后,我使用批量插入将文件中的所有记录插入到coredata中。

如果应用程序在前台或后台运行,则一切正常。

但是,当应用程序未运行/处于终止状态时,在收到推送通知时,上述过程将不起作用。

  

在检查设备日志时,我发现崩溃==>调度队列:com.apple.main-thread

任何帮助将不胜感激。

  

AppDelegate

func onPushReceived(_ pushManager: PushNotificationManager!, withNotification pushNotification: [AnyHashable : Any]!, onStart: Bool) {
    print("Push notification received: \(pushNotification)")

    //after identifying the push
    syncManager.downloadFile()

}
  

SyncManager

func downloadFile() {

    let url = URL(string: "my url")!
    let task = DownloadTaskManager.shared.activate().downloadTask(with: url)
    task.earliestBeginDate = Date().addingTimeInterval(60 * 1)
    task.resume()
    DownloadTaskManager.shared.onTaskCompleted = { () in
        self.updateProductsStatus()
    }
}
  

DownloadTaskManager

class DownloadTaskManager : NSObject {

    static var shared = DownloadTaskManager()

    var onTaskCompleted: () -> () = {}

    var isTaskCompleted = false {
        didSet {
            self.onTaskCompleted()
        }
    }

    let group = DispatchGroup()

    override private init() {
        super.init()
    }

    func activate() -> URLSession {
        let config = URLSessionConfiguration.background(withIdentifier:"backgroundTask")
        config.isDiscretionary = true
        config.sessionSendsLaunchEvents = true

        return URLSession(configuration: config, delegate: self, delegateQueue: nil)
    }

}

extension DownloadTaskManager: URLSessionDelegate, URLSessionDownloadDelegate {

    private func readProductsFromDatabase() -> Bool {

        var pageNo = 0

        group.enter()

        DispatchQueue.main.async {

            guard let managedContext = UIApplication.appDelegate?.getContext() else {
                fatalError("context not found")
            }

            let _ = DatabaseManager.deleteRecords(context: managedContext, entity: EntityType.product.rawValue)

            while(true) {

                let products = DatabaseManager.fetchProductsFromLocalDb(page: pageNo)

                let _  = DatabaseManager.insertBatchOfProducts(inManagedObjectContext: managedContext, productArray: products)
                if products.count < 1000 {
                    let products = DatabaseManager.getAllProducts(inManagedObjectContext: managedContext)
                    self.isTaskCompleted = true
                    break
                } else {
                    pageNo = pageNo + 1
                }
            }
        }

        group.wait()
        return true
    }


    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
        debugPrint("Download finished: \(location)")
        guard let httpResponse = downloadTask.response as? HTTPURLResponse,
            (200...299).contains(httpResponse.statusCode) else {
                print ("server error")
                return
        }
        do {
            let downloadedData = try Data(contentsOf: location)

                let documentDirectoryPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! as NSString
                let destinationPath = documentDirectoryPath.appendingPathComponent("Database.db")

                let databaseFileUrl = URL(fileURLWithPath: destinationPath)
                FileManager.default.createFile(atPath: databaseFileUrl.path,
                                               contents: downloadedData,
                                               attributes: nil)
                if FileManager.default.fileExists(atPath: databaseFileUrl.path) {
                    print("File present!") // Confirm that the file is here!
                }
            try FileManager.default.removeItem(at: location)
            let _ = readProductsFromDatabase()
            try FileManager.default.removeItem(at: databaseFileUrl)

        } catch {
            print(error.localizedDescription)
        }
    }

    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        debugPrint("Task completed: \(task), error: \(error)")
    }

    func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
        DispatchQueue.main.async {
            if let appDelegate = UIApplication.appDelegate {
                if let completionHandler = appDelegate.backgroundSessionCompletionHandler {
                    appDelegate.backgroundSessionCompletionHandler = nil
                    completionHandler()
                }
            }
        }
    }
}

0 个答案:

没有答案