问题
I updated my app to the latest swift 2.0 syntax. In doing so, My watchkit app has become broken. The issue is the watchkit app references a class that references the framework AVFoundation. WatchOS2 apparently now no longer supports some of the standard frameworks:
Support for network-based operations includes the following technologies:
WatchKit extensions can access the network directly through an NSURLSession object. WatchKit extensions have full access to the NSURLSession capabilities, including the ability to download files in the background. For information on how to use this class, see URL Loading System Programming Guide. The Watch Connectivity framework supports bidirectional communication between your Watch app and iOS app. Use this framework to coordinate activities between the two apps. See Communicating with Your Companion iOS App.
Available System Technologies for WatchKit
So now I cannot compile the watch kit code as "no such module found" is an error message when trying to use the AVFoundation framework. How can I get around this and keep referencing that class and framework in my apple watch app. Should I be communicating data between the phone and the watch? Is there a way to link the framework to the extension?
What I am trying to do is the following, in my InterfaceController:
override func willActivate() {
super.willActivate()
let defaultsShared = NSUserDefaults(suiteName: "somesharedappgroup")
let defaults = NSUserDefaults.standardUserDefaults()
if let barcodeString = defaultsShared!.objectForKey("barcode") as? String {
if let barcodeContent = RSUnifiedCodeGenerator.shared.generateCode(barcodeString, machineReadableCodeObjectType: AVMetadataObjectTypeCode39Code) {
barcode.setImage(barcodeContent)
label.setText("ID: \(barcodeString)")
} else {
label.setText("Please setup extensions in the settings of SHPID.")
barcode.setImage(nil)
}
} else {
label.setText("Please setup extensions in the settings of SHPID.")
barcode.setImage(nil)
}
}
The RSUnifiedCodeGenerator
being a class that utilizes AVFoundation to generate barcode images from strings. Furthermore, the type that generator takes is an AVObject: AVMetadataObjectTypeCode39Code. This solution worked well in the first WatchOS, but now remains broken in OS 2. I see that WatchConnectivity may be a solution, and have it just pass me the barcode from the phone itself, but that would require I stop supporting iOS 8. What is the best solution, if any, for using AVFoundation with WatchOS 2. If I can not do that, how else should I go about passing this image to the watch from the phone when called. Thanks.
回答1:
This is an example on how you could use WatchConnectivity for your app.
Please not that this example is rough and does not handle error. The session management should also get some attention for a stable product.
iPhone AppDelegate
import UIKit
import WatchConnectivity
import AVFoundation
import RSBarcodes
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, WCSessionDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
if WCSession.isSupported() {
let session = WCSession.defaultSession()
session.delegate = self
session.activateSession()
}
return true
}
// On Watch sends the message.
// Will not reply as we will push a data message with image.
func session(session: WCSession, didReceiveMessage message: [String : AnyObject]) {
if "generateBarcode" == message["id"] as! String {
let code = message["code"] as! String
let barcodeImage = RSUnifiedCodeGenerator.shared.generateCode(code,
machineReadableCodeObjectType: AVMetadataObjectTypeCode39Code)!
if WCSession.isSupported() {
let session = WCSession.defaultSession()
session.delegate = self
session.activateSession()
session.sendMessageData(UIImagePNGRepresentation(barcodeImage)!,
replyHandler: nil, errorHandler: nil)
}
}
}
}
Watch InterfaceController
import WatchKit
import Foundation
import WatchConnectivity
class InterfaceController: WKInterfaceController, WCSessionDelegate {
@IBOutlet var barcodeImage: WKInterfaceImage!
override func willActivate() {
super.willActivate()
if WCSession.isSupported() {
let session = WCSession.defaultSession()
session.delegate = self
session.activateSession()
// Send a message requesting a barcode image
session.sendMessage(
["id": "generateBarcode", "code": "2166529V"],
replyHandler: nil, // Do not handle response, iPhone will push a data message
errorHandler: nil)
}
}
// On iPhone pushes a data message
func session(session: WCSession, didReceiveMessageData messageData: NSData) {
barcodeImage.setImage(UIImage(data: messageData))
}
}
回答2:
I think that using WatchConnectivity is the right thing to do.
For previous version support if the only dealer breaker is AVMetadataObjectTypeCode39Code
, maybe you can print its value and pass it to the function directly?
来源:https://stackoverflow.com/questions/33006593/how-to-reference-non-supported-frameworks-in-watch-os-2