// // KBSkinInstallBridge.h // 主 App 与键盘扩展共享的皮肤安装桥接工具。 // #import NS_ASSUME_NONNULL_BEGIN /// 跨进程通知:主 App 请求键盘扩展安装皮肤。 extern NSString * const KBDarwinSkinInstallRequestNotification; /// 皮肤安装桥接错误域。 extern NSErrorDomain const KBSkinBridgeErrorDomain; /// 皮肤安装桥接错误码。 typedef NS_ENUM(NSUInteger, KBSkinBridgeErrorCode) { KBSkinBridgeErrorInvalidPayload = 1, KBSkinBridgeErrorContainerUnavailable, KBSkinBridgeErrorZipMissing, KBSkinBridgeErrorUnzipFailed, KBSkinBridgeErrorApplyFailed, }; typedef void (^KBSkinInstallConsumeCompletion)(BOOL success, NSError * _Nullable error); /// 已安装的皮肤记录,用于“我的皮肤”列表展示。 @interface KBSkinDownloadRecord : NSObject @property (nonatomic, copy) NSString *skinId; @property (nonatomic, copy) NSString *name; @property (nonatomic, copy, nullable) NSString *previewImage; @property (nonatomic, copy, nullable) NSString *zipURL; @property (nonatomic, assign) NSTimeInterval installedAt; @end @interface KBSkinInstallBridge : NSObject /// 默认图标短文件名映射(从 KBSkinIconMap.strings 读取)。 + (NSDictionary *)defaultIconShortNames; /// 主 App / 键盘扩展:通过远程 zip_url 下载并安装一套皮肤。 /// - skinJSON 结构与后端约定一致,至少包含: /// * id: 皮肤唯一标识 /// * name: 展示名称(可选,缺省为 id) /// * zip_url: 远程 Zip 地址(http/https) /// * key_icons: 按键 -> 图标“短文件名”映射(可选,不传则使用 defaultIconShortNames) /// - 内部会将 Zip 解压到 App Group/Skins//...,并使用 KBSkinManager 应用主题与背景图。 /// - 应用成功后,KBSkinManager 会广播皮肤变更通知,键盘扩展可立即感知。 + (void)installRemoteSkinWithJSON:(NSDictionary *)skinJSON completion:(nullable KBSkinInstallConsumeCompletion)completion; /// 主 App 侧:记录一个“从 bundle 解压皮肤”的请求,写入 App Group 并广播 Darwin 通知。 + (void)publishBundleSkinRequestWithId:(NSString *)skinId name:(NSString *)name zipName:(NSString *)zipName iconShortNames:(nullable NSDictionary *)iconShortNames; /// 读取当前 App Group 中待处理的请求。 + (nullable NSDictionary *)pendingRequestPayload; /// 清理 App Group 中的请求记录。 + (void)clearPendingRequest; /// 键盘扩展侧:如有请求则解压/应用皮肤。completion 中 success==YES 表示已处理并应用。 + (void)consumePendingRequestFromBundle:(NSBundle *)bundle completion:(nullable KBSkinInstallConsumeCompletion)completion; /// 枚举当前 App Group 中所有已解压的皮肤信息。 + (NSArray *)installedSkinRecords; /// 删除指定皮肤的本地资源目录(用于“我的皮肤 - 删除”)。 + (BOOL)removeInstalledSkinWithId:(NSString *)skinId error:(NSError * _Nullable __autoreleasing *)error; /// 记录皮肤元数据(下载完成后调用,方便“我的皮肤”读取)。 + (void)recordInstalledSkinWithId:(NSString *)skinId name:(NSString *)name preview:(nullable NSString *)preview zipURL:(nullable NSString *)zipURL; @end NS_ASSUME_NONNULL_END