Tôi đã tìm kiếm câu trả lời cho câu hỏi này trong một thời gian khá dài, vì vậy tôi nghĩ rằng tôi sẵn sàng mạo hiểm một số downvotes để đăng nó.Mã mẫu Apple cho nền mở rộng WatchKit Làm mới
Về cơ bản, tôi muốn tạo mã mẫu do Apple cung cấp để làm mới nền Apple Watch thực sự hoạt động (liên kết và mã bên dưới).
Tôi đã thử cả trong trình mô phỏng và trên iPhone 6s với Apple Watch Series 2 và các tác vụ nền không bao giờ được hoàn thành thành công đến thời điểm cập nhật thời gian. Tôi đã thử ghim ứng dụng đồng hồ vào thanh công cụ và tôi đã cố giữ ứng dụng ở nền trước và gửi ứng dụng tới nền, cả trong trình mô phỏng và trên đồng hồ thực tế. Tôi thậm chí đã cố gắng chờ gần một năm để xem liệu Xcode hay Apple Watch có nhận được bản cập nhật có thể làm cho nó hoạt động không.
Có ai đã sửa đổi thành công mã được Apple cung cấp để mã hoạt động không?
Bạn có thể tải toàn bộ dự án mẫu Runnable đây: WatchBackgroundRefresh: Using WKRefreshBackgroundTask to update WatchKit apps in the background
/*
Copyright (C) 2016-2017 Apple Inc. All Rights Reserved.
See LICENSE.txt for this sample’s licensing information
Abstract:
The main interface controller.
*/
import WatchKit
import Foundation
class MainInterfaceController: WKInterfaceController, WKExtensionDelegate, URLSessionDownloadDelegate {
// MARK: Properties
let sampleDownloadURL = URL(string: "http://devstreaming.apple.com/videos/wwdc/2015/802mpzd3nzovlygpbg/802/802_designing_for_apple_watch.pdf?dl=1")!
@IBOutlet var timeDisplayLabel: WKInterfaceLabel!
private let dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .none
formatter.timeStyle = .long
return formatter
}()
// MARK: WKInterfaceController
override func awake(withContext context: Any?) {
super.awake(withContext: context)
// Configure interface objects here.
WKExtension.shared().delegate = self
updateDateLabel()
}
// MARK: WKExtensionDelegate
func handle(_ backgroundTasks: Set<WKRefreshBackgroundTask>) {
for task : WKRefreshBackgroundTask in backgroundTasks {
print("received background task: ", task)
// only handle these while running in the background
if (WKExtension.shared().applicationState == .background) {
if task is WKApplicationRefreshBackgroundTask {
// this task is completed below, our app will then suspend while the download session runs
print("application task received, start URL session")
scheduleURLSession()
}
}
else if let urlTask = task as? WKURLSessionRefreshBackgroundTask {
let backgroundConfigObject = URLSessionConfiguration.background(withIdentifier: urlTask.sessionIdentifier)
let backgroundSession = URLSession(configuration: backgroundConfigObject, delegate: self, delegateQueue: nil)
print("Rejoining session ", backgroundSession)
}
// make sure to complete all tasks, even ones you don't handle
task.setTaskCompleted()
}
}
// MARK: Snapshot and UI updating
func scheduleSnapshot() {
// fire now, we're ready
let fireDate = Date()
WKExtension.shared().scheduleSnapshotRefresh(withPreferredDate: fireDate, userInfo: nil) { error in
if (error == nil) {
print("successfully scheduled snapshot. All background work completed.")
}
}
}
func updateDateLabel() {
let currentDate = Date()
timeDisplayLabel.setText(dateFormatter.string(from: currentDate))
}
// MARK: URLSession handling
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
print("NSURLSession finished to url: ", location)
updateDateLabel()
scheduleSnapshot()
}
func scheduleURLSession() {
let backgroundConfigObject = URLSessionConfiguration.background(withIdentifier: NSUUID().uuidString)
backgroundConfigObject.sessionSendsLaunchEvents = true
let backgroundSession = URLSession(configuration: backgroundConfigObject)
let downloadTask = backgroundSession.downloadTask(with: sampleDownloadURL)
downloadTask.resume()
}
// MARK: IB actions
@IBAction func ScheduleRefreshButtonTapped() {
// fire in 20 seconds
let fireDate = Date(timeIntervalSinceNow: 20.0)
// optional, any SecureCoding compliant data can be passed here
let userInfo = ["reason" : "background update"] as NSDictionary
WKExtension.shared().scheduleBackgroundRefresh(withPreferredDate: fireDate, userInfo: userInfo) { (error) in
if (error == nil) {
print("successfully scheduled background task, use the crown to send the app to the background and wait for handle:BackgroundTasks to fire.")
}
}
}
}
Sau đây là kết quả khi chạy trên giả lập. đầu ra tương tự (nhưng không nhất thiết phải giống hệt nhau) khi chạy trong các cấu hình khác:
successfully scheduled background task, use the crown to send the app to the background and wait for handle:BackgroundTasks to fire.
received background task: <WKSnapshotRefreshBackgroundTask: 0x7b019030>
received background task: <WKApplicationRefreshBackgroundTask: 0x7a711290>
application task received, start URL session
Một số lời khuyên chung: sử dụng quy ước đặt tên Swift, là camelCase thấp hơn cho các tên hàm ('scheduleRefreshButtonTapped()'). Về câu hỏi của bạn: vui lòng cung cấp thêm ngữ cảnh về nội dung không hoạt động. Lịch trình có thành công không? 'Handle (backgroundTasks:') có được gọi là không? Hãy cụ thể hơn. –
@ DávidPásztor Cảm ơn, tôi chắc chắn sẽ sửa chữa các quy ước đặt tên khi tôi kết hợp bất kỳ mã Apple nào vào dự án của riêng tôi. Đối với các chi tiết cụ thể về những gì không hoạt động, tôi đã chỉnh sửa câu hỏi để thêm một mẫu đầu ra tương ứng. – PerpetualStudent
Bạn đã thử mã này trên trình mô phỏng đồng hồ được kết nối với iPhone thực hay trên Apple Watch thực được kết nối với iPhone. –