赞
踩
=============================================
①步骤
把 xxxxxx.p12 转换成 xxxx.cer 和 xxxx.pem
①转换代码
openssl pkcs12 -in my.p12 -out xxx.pem -nodes
<得到:xxx.pem>两个任选一
openssl pkcs12 -clcerts -nokeys -out xxx.pem -in my.p12
<得到:xxx.pem>两个任选一
openssl pkcs12 -in my.p12 -out xxxx.crt -nokeys -clcerts
openssl x509 -inform pem -in xxxx.crt -outform der -out xxxx.cer
<得到:xxxx.cer>
得到文件=保存起来=等会代码签名用===
通过 xxxxx.p12转换
得到 xxxx.pem
得到 xxxx.cer
====目前4个文件 列表=
//自备文件
xxxxx.p12
xxxxx.mobileprovision
//通过xxx.p12转换得到文件
xxxx.pem
xxxx.cer
===============================================
//签名调用(xddSigning signIpaAtPath)
NSString *cachepath=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];
//签名保存文件路径
NSString *outputPath=[cachepath stringByAppendingPathComponent:@“Alook_qqqq_sign.ipa”];
//待签名文件路径<我是放到程序目录>线上可以读取Document
NSString *ipaPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@“Alook.ipa”];
[xddSigning signIpaAtPath:ipaPath outputPath:outputPath withCompletionHandler:^(NSError * error) {
if(error){
[xddCode xddLog:[NSString stringWithFormat:@"签名:%@",@"失败"]];
}else{
[xddCode xddLog:[NSString stringWithFormat:@"签名成功:路径=%@",outputPath]];
}
}];
// signIpaAtPath 签名具体实现
(void)signIpaAtPath:(NSString*)ipaPath outputPath:(NSString*)outputPath withCompletionHandler:(void (^)(NSError *))completionHandler {
// 1. Unpack IPA to a temporary directory.
NSError *error;
NSString *unpackedDirectory;
if (![xddCode unpackIpaAtPath:ipaPath outDirectory:&unpackedDirectory error:&error]) {
completionHandler(error);
return;
}
// 2. Sign its main bundle via above method.
// The bundle will be located at //Payload/*.app internally
NSString *zipFilename = [ipaPath lastPathComponent];
zipFilename = [zipFilename stringByReplacingOccurrencesOfString:@“.ipa” withString:@“”];
NSString *payloadDirectory = [NSString stringWithFormat:@“%@/Payload”, unpackedDirectory];
NSArray *files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:payloadDirectory error:&error];
if (error) {
completionHandler(error);
return;
} else if (files.count == 0) {
NSError *err = [xddCode _errorFromString:@"Payload directory of IPA has no contents"];
completionHandler(err);
return;
}
NSString *dotAppDirectory = @“”;//获取程序包
for (NSString *directory in files) {
if ([directory containsString:@".app"]) {
dotAppDirectory = directory;
break;
}
}
//…/Payload/xxxx.app
NSString *bundleDirectory = [NSString stringWithFormat:@“%@/%@”, payloadDirectory, dotAppDirectory];
NSLog(@“Signing bundle at path ‘%@’”, bundleDirectory);
[xddCode xddLog:[NSString stringWithFormat:@“正在签名:%@”,bundleDirectory]];
//开始签名
[self signBundleAtPath:bundleDirectory withCompletionHandler:^(NSError *err) {
if (err) { completionHandler(err); return; } // 3. Repack IPA to output path NSError *error2; if (![xddCode repackIpaAtPath:[NSString stringWithFormat:@"%@/%@", [xddCode applicationTemporaryDirectory], zipFilename] toPath:outputPath error:&error2]) { completionHandler(error2); } else { // Success! completionHandler(nil); [xddCode xddLog:[NSString stringWithFormat:@"签名完毕:paAtPath=%@",[NSString stringWithFormat:@"%@/%@", [xddCode applicationTemporaryDirectory], zipFilename]]]; [xddCode xddLog:[NSString stringWithFormat:@"签名完毕:toPath=%@",outputPath]]; }
}];
}
(void)signBundleAtPath:(NSString*)path withCompletionHandler:(void (^)(NSError *error))completionHandler {
// We need to handle application extensions, e.g. watchOS applications and VPN plugins etc.
// These are stored in the bundle’s root directory at the following locations:
// - /Plugins
// - /Watch
// Therefore, recurse through those directories as required before continuing for the root directory.
dispatch_group_t dispatch_group = dispatch_group_create();
NSMutableArray * __block subBundleErrors = [NSMutableArray array];
if ([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@“%@/PlugIns”, path]]) {
// Recurse through the plugins. for (NSString *subBundle in [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[NSString stringWithFormat:@"%@/PlugIns", path] error:nil]) { NSString *__block subBundlePath = [NSString stringWithFormat:@"%@/PlugIns/%@", path, subBundle]; // Enter the dispatch group dispatch_group_enter(dispatch_group); NSLog(@"Handling sub-bundle: %@", subBundlePath); // Sign the bundle [self signBundleAtPath:subBundlePath withCompletionHandler:^(NSError *error) { if (error) [subBundleErrors addObject:error]; NSLog(@"Finished sub-bundle: %@", subBundlePath); dispatch_group_leave(dispatch_group); }]; }
}
if ([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@“%@/Watch”, path]]) {
// Recurse through the watchOS stuff. for (NSString *subBundle in [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[NSString stringWithFormat:@"%@/Watch", path] error:nil]) { NSString * __block subBundlePath = [NSString stringWithFormat:@"%@/Watch/%@", path, subBundle]; // Enter the dispatch group dispatch_group_enter(dispatch_group); NSLog(@"Handling sub-bundle: %@", subBundlePath); // Sign the bundle [self signBundleAtPath:subBundlePath withCompletionHandler:^(NSError *error) { if (error) [subBundleErrors addObject:error]; NSLog(@"Handled sub-bundle: %@", subBundlePath); dispatch_group_leave(dispatch_group); }]; }
}
// Wait on sub-bundles to finish, if needed.
dispatch_group_wait(dispatch_group, DISPATCH_TIME_FOREVER);
if (subBundleErrors.count > 0) {
// Errors when handling sub-bundles!
for (NSError *err in subBundleErrors) {
NSLog(@"Error: %@", err.localizedDescription);
}
completionHandler([subBundleErrors lastObject]);
return;
}
// 1. Read Info.plist to gain the applicationId and binaryLocation.
// 2. Get provisioning profile and certificate info
// 3. Sign bundle
NSDictionary *infoplist = [NSDictionary dictionaryWithContentsOfFile:[NSString stringWithFormat:@“%@/Info.plist”, path]];
if (!infoplist || [infoplist allKeys].count == 0) {
NSError *error = [xddCode _errorFromString:@"Failed to open Info.plist!"];
completionHandler(error);
return;
}
// Find the systemType for this bundle.
NSString *platformName = [infoplist objectForKey:@“DTPlatformName”];
EESystemType systemType = -1;
if ([platformName isEqualToString:@“iphoneos”]) {
systemType = EESystemTypeiOS;
} else if ([platformName isEqualToString:@“watchos”]) {
systemType = EESystemTypewatchOS;
} else if ([platformName isEqualToString:@“tvos”]) {
systemType = EESystemTypetvOS;
} else {
// Base case, assume iOS.
systemType = EESystemTypeiOS;
}
NSLog(@“Platform: %@ for bundle: %@”, platformName, [path lastPathComponent]);
NSString *applicationId = [infoplist objectForKey:@“CFBundleIdentifier”];
NSString *binaryLocation = [path stringByAppendingFormat:@“/%@”, [infoplist objectForKey:@“CFBundleExecutable”]];
NSLog(@“applicationId: %@ for bundle: %@”, applicationId, [path lastPathComponent]);
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
搭建自己的知识框架,全面提升自己的技术体系,并且往底层源码方向深入钻研。
大多数技术人喜欢用思维脑图来构建自己的知识体系,一目了然。这里给大家分享一份大厂主流的Android架构师技术体系,可以用来搭建自己的知识框架,或者查漏补缺;
对应这份技术大纲,我也整理了一套Android高级架构师完整系列的视频教程,主要针对3-5年Android开发经验以上,需要往高级架构师层次学习提升的同学,希望能帮你突破瓶颈,跳槽进大厂;
最后我必须强调几点:
1.搭建知识框架可不是说你整理好要学习的知识顺序,然后看一遍理解了能复制粘贴就够了,大多都是需要你自己读懂源码和原理,能自己手写出来的。
2.学习的时候你一定要多看多练几遍,把知识才吃透,还要记笔记,这些很重要! 最后你达到什么水平取决你消化了多少知识
3.最终你的知识框架应该是一个完善的,兼顾广度和深度的技术体系。然后经过多次项目实战积累经验,你才能达到高级架构师的层次。
你只需要按照在这个大的框架去填充自己,年薪40W一定不是终点,技术无止境
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
]
对应这份技术大纲,我也整理了一套Android高级架构师完整系列的视频教程,主要针对3-5年Android开发经验以上,需要往高级架构师层次学习提升的同学,希望能帮你突破瓶颈,跳槽进大厂;
最后我必须强调几点:
1.搭建知识框架可不是说你整理好要学习的知识顺序,然后看一遍理解了能复制粘贴就够了,大多都是需要你自己读懂源码和原理,能自己手写出来的。
2.学习的时候你一定要多看多练几遍,把知识才吃透,还要记笔记,这些很重要! 最后你达到什么水平取决你消化了多少知识
3.最终你的知识框架应该是一个完善的,兼顾广度和深度的技术体系。然后经过多次项目实战积累经验,你才能达到高级架构师的层次。
你只需要按照在这个大的框架去填充自己,年薪40W一定不是终点,技术无止境
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-TvEbh8oG-1712847913404)]
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。