You have completed many necessary actions:
What was said, a few comments:
"" " "" " ". , plist, , .
, (.. "" ). , .
debugPrint, Xcode. , Xcode. , , Xcode.
os_log (. WWDC 2016 ) UserNotifications (. WWDC 2016 ), , - . (, plist). - print/debugPrint, , Xcode. , .
PGDev , , . ( Wi-Fi, , , ..).
, , ( Xcode) Wi-Fi , iPhone 7+ 10 .
. :
, URLSession - (.. , ). , , . (, , .)
, , . ( , .) , Apple , .
, , , , , , , , . , , , , , (30 , IIRC). , , / .
, . , , (, ). , reset .
, , . UserNotifications os_log, , Xcode (.. print debugPrint ):
import UIKit
import UserNotifications
import os.log
@UIApplicationMain
class AppDelegate: UIResponder {
var window: UIWindow?
fileprivate var fetchRequest: URLRequest {
var request: URLRequest = ...
return request
}
fileprivate let log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "log")
}
extension AppDelegate: UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
application.setMinimumBackgroundFetchInterval(UIApplicationBackgroundFetchIntervalMinimum)
os_log("didFinishLaunching", log: log)
UNUserNotificationCenter.current().delegate = self
return true
}
func applicationWillEnterForeground(_ application: UIApplication) {
os_log("applicationWillEnterForeground", log: log)
}
func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
os_log("performFetchWithCompletionHandler", log: log)
processRequest(completionHandler: completionHandler)
}
}
extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
os_log("willPresent %{public}@", log: log, notification)
completionHandler(.alert)
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
os_log("didReceive %{public}@", log: log, response)
completionHandler()
}
}
extension AppDelegate {
func processRequest(completionHandler: ((UIBackgroundFetchResult) -> Void)? = nil) {
let task = URLSession.shared.dataTask(with: fetchRequest) { data, response, error in
var result = UIBackgroundFetchResult.failed
var message = "Unknown"
defer {
self.postNotification(message)
completionHandler?(result)
}
guard let data = data, error == nil else {
message = "Network error: \(error?.localizedDescription ?? "Unknown error")"
return
}
guard
let json = try? JSONSerialization.jsonObject(with: data),
let dictionary = json as? [String: Any],
let success = dictionary["success"] as? Bool else {
message = "JSON parsing failed"
return
}
if success {
result = .newData
message = "New Data"
} else {
result = .noData
message = "No Data"
}
}
task.resume()
}
func postNotification(_ message: String) {
let content = UNMutableNotificationContent()
content.title = "MyApp"
content.body = message
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false)
let notification = UNNotificationRequest(identifier: "timer", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(notification)
os_log("%{public}@", log: self.log, message)
}
}
:
import UIKit
import UserNotifications
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
UNUserNotificationCenter.current().requestAuthorization(options: [.sound, .alert]) { granted, error in
if !granted {
DispatchQueue.main.async {
let alert = UIAlertController(title: nil, message: "Need notification", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
}
let url = URL(string: "http://example.com")!
let request = URLRequest(url: url)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
DispatchQueue.main.async {
let alert = UIAlertController(title: nil, message: error?.localizedDescription ?? "Sample request finished", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(alert, animated: true)
}
}
task.resume()
}
}