2023-04-13 iOS下载安装桌面图标描述文件

实现colorful widget主题图标下载安装效果,其实是一个快捷启动入口

1、依赖 CocoaHTTPServer 搭建一个本地服务器,提供mobileconfig下载,https://img.ibestfanli.com/CocoaHTTPServer.zip
2、使用到 SFSafariViewController,SFSafariViewController需要下载实时打包的图标mobileconfig文件,下载完系统弹窗提示跳转安装页面

一、启动本地服务器

// 端口
static NSInteger const LocalServerPort = 8090;
// host
static NSString * const LocalHost = @"127.0.0.1";

_localHttpServer = [[HTTPServer alloc] init];
[_localHttpServer setType:@"_http.tcp"];
[_localHttpServer setPort:LocalServerPort];
[_localHttpServer setInterface:LocalHost];
NSString *rootPath = [SystemUtil appDocumentPathAppendingFolder:@"local"];
//  创建并指定服务器根目录,也是存储下载mobileconfig文件的目录
NSString *originPath = [NSString stringWithFormat:@"%@/local",[[NSBundle mainBundle] bundlePath]];
// 把工程内的Web拷贝到document/local/
[SystemUtil copyFilesWithOldFolder:originPath toPath:rootPath];
[_localHttpServer setDocumentRoot:rootPath];

二、打包创建mobileconfig文件

手动创建需要用Apple Configurator配置一个WebClip,


截屏2023-04-13 18.45.45.png

但我们示例使用代码创建:

/// 配置一个PayloadContent
/// - Parameters:
///   - icon: 图标data数据
///   - label: 图标展示标题
///   - url: 跳转的app scheme
+ (NSMutableDictionary *)initWithIcon:(NSData *)icon label:(NSString *)label url:(NSString *)url {
    PayloadContent *content = [[PayloadContent alloc] init];
    NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
    NSString *uuid = [FCUUID uuid];
    content.FullScree = YES;
    content.IgnoreManifestScope = NO;
    content.IsRemovable = YES;
    content.Label = label;
    content.PayloadDescription = @"Configures settings for a web clip";
    content.PayloadDisplayName = [NSString stringWithFormat:@"%@ Icon",label];
    content.PayloadIdentifier = [NSString stringWithFormat:@"com.apple.webClip.managed.%@",uuid];
    content.PayloadType = @"com.apple.webClip.managed";
    content.PayloadUUID = uuid;
    content.PayloadVersion = 1;
    content.Precomposed = NO;
    content.TargetApplicationBundleIdentifier = [DataCenter shareCenter].appInfo.bundleId;
    content.URL = url;
    dict = [content modelToJSONObject];
    dict[@"Icon"] = icon;
    return dict;
}
@end

@implementation WebClip

/// 生成一个mobileconfig文件的配置字典
/// - Parameters:
///   - name: 文件名字
///   - array: PayloadContent数组
+ (NSMutableDictionary *)initWithName:(NSString *)name contents:(NSArray *)array {
    WebClip *clip = [[WebClip alloc] init];
    NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
    NSString *uuid = [FCUUID uuid];
    clip.PayloadDisplayName = name;
    clip.PayloadIdentifier = uuid;
    clip.PayloadRemovalDisallowed = NO;
    clip.PayloadType = @"Configuration";
    clip.PayloadUUID = uuid;
    clip.PayloadVersion = 1;
    dict = [clip modelToJSONObject];
    dict[@"PayloadContent"] = array;
    return dict;
}
@end
// 保存sige.mobileconfig到本地服务器的根目录
- (BOOL)saveMobileconfigFile {
    NSMutableDictionary *dict = [WebClip initWithName:@"图标描述文件" contents:[self testMakeMobileconfig]];
    // 保存sige.mobileconfig到本地服务器的根目录
    NSString *filePath = [SystemUtil appDocumentPathAppendingFile:@"local/sige.mobileconfig" replace:YES];
    BOOL write = [dict writeToURL:[NSURL fileURLWithPath:filePath] atomically:YES];
    return write;
}
/// 生成PayloadContent数据
- (NSMutableArray*)testMakeMobileconfig {
    NSMutableArray *payloadArray = [[NSMutableArray alloc] init];
    for (int i=0; i<10; i++) {
        NSData *imgData = UIImageJPEGRepresentation([UIImage imageNamed:@"ic_vip_tick"], 0.8);
        NSMutableDictionary *dict = [PayloadContent initWithIcon:imgData label:[NSString stringWithFormat:@"标题 %@",@(i)] url:@"mqq://"];
        [payloadArray addObject:dict];
    }
    return payloadArray;
}

三、SFSafariViewController访问一个本地H5,http://127.0.0.1:8090/web.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>教程</title>
  </head>
  <body>
    <div class="panel">
      <p class="titleText">下载文件,然后点击「允许」</p>
      <a href="http://127.0.0.1:8090/sige.mobileconfig"><p class="btn">下载</p></a>
      <p class="titleText2">
        进入「设置」页面,点击进入已下载的描述文件,点击右上方「安装」
      </p>
    </div>
    </style>
  </body>
</html>

点击下载后,文件就会保存到VPN与设备管理页,点击安装即可;

此时安装的描述文件,是未签名的,可以使用服务端签名或者本地签名;
ios 描述文件 本地签名看这里

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容