使用 SiriKit 在 Intents UI 中显示图像

Show images in Intents UI using SiriKit

我正在使用 SiriKit 开发一个简单的照片搜索。我可以在主 viewcontroller 上搜索和显示图像,但无法使用 IntentsUI 框架在 Intents UI 上显示图像。我遵循了这个 tutorial 但它缺少 Intents UI 实现。这是我到目前为止所做的。

IntentHandler.swift

class IntentHandler: INExtension, INSearchForPhotosIntentHandling {

    override func handler(for intent: INIntent) -> Any {

        return self
    }

    // MARK: - INSearchForPhotosIntentHandling

    func resolveDateCreated(forSearchForPhotos intent: INSearchForPhotosIntent, with completion: @escaping (INDateComponentsRangeResolutionResult) -> Void) {

        if intent.dateCreated != nil {
            completion(INDateComponentsRangeResolutionResult.success(with: intent.dateCreated!))
        }
        else{
            completion(INDateComponentsRangeResolutionResult.needsValue())
        }
    }


    func confirm(searchForPhotos intent: INSearchForPhotosIntent, completion: @escaping (INSearchForPhotosIntentResponse) -> Void) {

        let response = INSearchForPhotosIntentResponse(code: .ready, userActivity: nil)
        completion(response)
    }

    func handle(searchForPhotos intent: INSearchForPhotosIntent, completion: @escaping (INSearchForPhotosIntentResponse) -> Void) {
        let response = INSearchForPhotosIntentResponse(code:.continueInApp,userActivity: nil)

        if intent.dateCreated != nil {
            let calendar = Calendar(identifier: .gregorian)
            let startDate = calendar.date(from:(intent.dateCreated?.startDateComponents)!)
            response.searchResultsCount = photoSearchFrom(startDate!)

        }
        completion(response)
    }


    // MARK: - Search Photos 

    func photoSearchFrom(_ startDate: Date) -> Int {

        let fetchOptions = PHFetchOptions()
        fetchOptions.predicate = NSPredicate(format: "creationDate >= %@", startDate as CVarArg)

        let fetchResult = PHAsset.fetchAssets(with: PHAssetMediaType.image,
                                              options: fetchOptions)
        return fetchResult.count
    }

}

AppDelegate.Swift

class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {

        // implement to handle user activity created by Siri or by our SiriExtension
        let viewController = self.window?.rootViewController as! PhotoViewController
        viewController.handleActivity(userActivity)

        return true
    }
}

PhotoViewController.swift

class ViewController: UIViewController {

    @IBOutlet weak var imageView: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()
        INPreferences.requestSiriAuthorization { (status) in
            print(status)
        }
    }

    func handleActivity(_ userActivity: NSUserActivity) {

        let intent = userActivity.interaction?.intent as! INSearchForPhotosIntent

        if (intent.dateCreated?.startDateComponents) != nil {
            let calendar = Calendar(identifier: .gregorian)
            let startDate = calendar.date(from:(intent.dateCreated?.startDateComponents)!)

            self.displayPhoto(startDate!)
        }
    }


    func displayPhoto(_ startDate: Date) {

        let fetchOptions = PHFetchOptions()
        fetchOptions.predicate = NSPredicate(format: "creationDate >= %@", startDate as CVarArg)
        let fetchResult = PHAsset.fetchAssets(with:
            PHAssetMediaType.image, options: fetchOptions)

        let imgManager = PHImageManager.default()

        imgManager.requestImage(for: fetchResult.firstObject! as PHAsset,
                                targetSize: view.frame.size,
                                contentMode: PHImageContentMode.aspectFill,
                                options: nil, 
                                resultHandler: { (image, _) in
                                    self.imageView.image = image
        })
    }
}

现在 IntentViewController.swift

class IntentViewController: UIViewController, INUIHostedViewControlling {

    @IBOutlet weak var imageView:UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        INPreferences.requestSiriAuthorization { (status) in
            print("From IntentViewController: \(status)")
        }
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)
        print("IntentViewController-> viewDidLoad")
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // MARK: - INUIHostedViewControlling

    // Prepare your view controller for the interaction to handle.
    func configure(with interaction: INInteraction!, context: INUIHostedViewContext, completion: ((CGSize) -> Void)!) {

        print("From configure")

        let intent = interaction?.intent as! INSearchForPhotosIntent

        if (intent.dateCreated?.startDateComponents) != nil {
            let calendar = Calendar(identifier: .gregorian)
            let startDate = calendar.date(from:(intent.dateCreated?.startDateComponents)!)
            self.displayPhoto(startDate!)
        }

        if let completion = completion {
            completion(self.desiredSize)
        }
    }

    var desiredSize: CGSize {
        return self.extensionContext!.hostedViewMaximumAllowedSize
    }

    func displayPhoto(_ startDate: Date) {

        let fetchOptions = PHFetchOptions()
        fetchOptions.predicate = NSPredicate(format: "creationDate >= %@", startDate as CVarArg)
        let fetchResult = PHAsset.fetchAssets(with:
            PHAssetMediaType.image, options: fetchOptions)

        let imgManager = PHImageManager.default()

        imgManager.requestImage(for: fetchResult.firstObject! as PHAsset,
                                targetSize: view.frame.size,
                                contentMode: PHImageContentMode.aspectFill,
                                options: nil,
                                resultHandler: { (image, _) in
                                    self.imageView.image = image
        })
    }
}

我是否必须在 IntentHandler.swift 文件的 handle 方法中编写任何额外的代码才能使用 Intents UI 显示图像?我不想在应用程序中继续,实际上我想要 Intents UI 中的结果。提前致谢。

好的。我在苹果 documentation.

上找到了它

You can provide an Intents UI extension if you are supporting intents in the following domains:

Messaging

Payments

Ride booking

Workouts

这表明我无法使用 Intents UI 进行照片搜索。