iOS NSExtensionContext学习

在iOS 8中,UIViewController新增了一个扩展上下文的属性extensionContext,用以处理容器应用和扩展之间的通信,上下文的类型是NSExtensionContext。我们可以通过它来获取相应数据,进行返回容器应用的界面等操作。

我们可以先看一下NSExtensionContext的定义

// Class representing the extension request's context

@available(iOS 8.0, *)
open class NSExtensionContext : NSObject {

    // 该数据存放着容器应用传入给NSExtensionContext的NSExtensionItem数组。其中每个NSExtensionItem标识了一种类型的数据,要想获取数据主要操作该属性。
    open var inputItems: [Any] { get }

    // 通知载体程序扩展已经完成请求。调用该方法后,扩展的UI会关闭并返回容器程序中。其中的items参数就是返回载体程序的数据项。
    open func completeRequest(returningItems items: [Any]?, completionHandler: ((Bool) -> Swift.Void)? = nil)

    // 通知载体程序的扩展已取消请求。调用该方法后,扩展的UI会关闭并返回容器程序中。其中error参数为错误的描述信息。
    open func cancelRequest(withError error: Error)

    // 打开容器应用的一个方法
    open func open(_ URL: URL, completionHandler: ((Bool) -> Swift.Void)? = nil)
}

// NSExtensionItem的userInfo属性中对应的错误信息键名
@available(iOS 8.0, *)
public let NSExtensionItemsAndErrorsKey: String
extension NSNotification.Name {

    // 载体程序将要返回前台通知
    @available(iOS 8.2, *)
    public static let NSExtensionHostWillEnterForeground: NSNotification.Name

    // 载体程序进入后台通知
    @available(iOS 8.2, *)
    public static let NSExtensionHostDidEnterBackground: NSNotification.Name

    // 载体程序被挂起通知
    @available(iOS 8.2, *)
    public static let NSExtensionHostWillResignActive: NSNotification.Name

    // 载体程序被激活通知
    @available(iOS 8.2, *)
    public static let NSExtensionHostDidBecomeActive: NSNotification.Name
}

通过对NSExtensionContext的了解,我们发现如果需要操作NSExtensionContext的数据的时候,我们需要了解它的inputItems属性。inputItems是包含NSExtensionItem类型对象的数组,那么,需要处理里面的数据就应该先了解一下NSExtensionItem的数据结构。

@interface NSExtensionItem : NSObject<NSCopying, NSSecureCoding>

// 标题
@property(nullable, copy, NS_NONATOMIC_IOSONLY) NSAttributedString *attributedTitle;

// 内容
@property(nullable, copy, NS_NONATOMIC_IOSONLY) NSAttributedString *attributedContentText;

// 附件数组,包含图片、视频、连接等资源,封装在NSItemProvider类型中
@property(nullable, copy, NS_NONATOMIC_IOSONLY) NSArray *attachments;

// 一个key-value结构的数据。NSExtensionItem中的属性都会在这个属性中一一映射。
@property(nullable, copy, NS_NONATOMIC_IOSONLY) NSDictionary *userInfo;

@end

// 对应userInfo结构中的NSExtensionItem属性的键名

// 标题的键名
FOUNDATION_EXTERN NSString * __null_unspecified const NSExtensionItemAttributedTitleKey NS_AVAILABLE(10_10, 8_0);
// 内容的键名
FOUNDATION_EXTERN NSString * __null_unspecified const NSExtensionItemAttributedContentTextKey NS_AVAILABLE(10_10, 8_0);
// 附件的键名
FOUNDATION_EXTERN NSString * __null_unspecified const NSExtensionItemAttachmentsKey NS_AVAILABLE(10_10, 8_0);

从上面的定义可以看出除了文本内容以外,其他类型的内容都是作为附件存储的,而附件又是封装在一个叫做NSItemProvider类型中的,下面我们接着了解一下NSItemProvider的定义。

open class NSItemProvider : NSObject, NSCopying {

    // 初始化方法,item参数表示为附件数据,typeIdentifier表示为附件对应的类型标示
    public init(item: NSSecureCoding?, typeIdentifier: String?)

    // 根据指定的文件路径进行初始化
    public convenience init?(contentsOf fileURL: URL!)

    // 为资源类型自定义加载过程,这个方法主要针对自定义资源使用,例如自己定的类或者文件格式等。当调用`open func loadItem(forTypeIdentifier typeIdentifier: String, options: [AnyHashable : Any]? = nil, completionHandler: NSItemProvider.CompletionHandler? = nil)`方法时就会出发定义的加载过程
    open func registerItem(forTypeIdentifier typeIdentifier: String, loadHandler: @escaping NSItemProvider.LoadHandler)

    // Returns the list of registered type identifiers
    open var registeredTypeIdentifiers: [Any] { get }

    // 用于判断是否有typeIdentifier所指定的资源存在,存在则返回true,否则返回false.该方法结合`open func loadItem(forTypeIdentifier typeIdentifier: String, options: [AnyHashable : Any]? = nil, completionHandler: NSItemProvider.CompletionHandler? = nil)`方法使用。
    open func hasItemConformingToTypeIdentifier(_ typeIdentifier: String) -> Bool

    // 加载typeIdentifier指定的资源。加载是一个异步过程,加载完成会触发completionHandler回调。
    open func loadItem(forTypeIdentifier typeIdentifier: String, options: [AnyHashable : Any]? = nil, completionHandler: NSItemProvider.CompletionHandler? = nil)
}

// Common keys for the item provider options dictionary.
@available(iOS 8.0, *)
public let NSItemProviderPreferredImageSizeKey: String // NSValue of CGSize or NSSize, specifies image size in pixels.

extension NSItemProvider {

    // 自定义的预览图处理回调
    @available(iOS 8.0, *)
    open var previewImageHandler: NSItemProvider.LoadHandler?


    // 加载资源的预览图片
    @available(iOS 8.0, *)
    open func loadPreviewImage(options: [AnyHashable : Any]! = [:], completionHandler: NSItemProvider.CompletionHandler!)
}

// Keys used in property list items received from or sent to JavaScript code

// If JavaScript code passes an object to its completionFunction, it will be placed into an item of type kUTTypePropertyList, containing an NSDictionary, under this key.
@available(iOS 8.0, *)
public let NSExtensionJavaScriptPreprocessingResultsKey: String

// Arguments to be passed to a JavaScript finalize method should be placed in an item of type kUTTypePropertyList, containing an NSDictionary, under this key.
@available(iOS 8.0, *)
public let NSExtensionJavaScriptFinalizeArgumentKey: String
extension NSItemProvider {
    @available(iOS 8.0, *)
    public class let errorDomain: String
    // 错误码
    @available(iOS 8.0, *)
    public enum ErrorCode : Int {
        case unknownError
        case itemUnavailableError
        case unexpectedValueClassError
        @available(iOS 9.0, *)
        case unavailableCoercionError
    }
    public typealias CompletionHandler = (NSSecureCoding?, Error!) -> Swift.Void
    public typealias LoadHandler = (NSItemProvider.CompletionHandler!, Swift.AnyClass!, [AnyHashable : Any]!) -> Swift.Void
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值