2019-06-10 16:39:34 m0_37873793 阅读数 225

1、XCode->Window->Organizer(图一)

2、找到对应的安装包并双击点击show in Finder

3、双击.xcarchive文件显示包内容

4、双击.app.dsYM文件显示报内容

5、按照如下路径找到APP名字的文件

6、打开终端输入(xcrun atos -arch arm64 -o )然后(将appname文件拖到此处,如下图)

7、输入(-l)+ (崩溃日志中的ADDR如下图) + (APPname后面对应的一串字符如下图的篮圈内的文字)输入完成之后回车就可以了

8、最终结果如下,结果会有类别,和行数都会有的

2015-10-08 10:46:58 ruyi366 阅读数 2601


参考文档:http://my.oschina.net/heweipo/blog/382942


IOS IPA文件中包含Info.plist文件,类似于Android的AndroidManifest.xml,因此想获取IOS版本相关信息,就需要解析其Info.plist文件。参考文档中有详细的描述,但编译不过,调用的函数名搞错了,以如下代码为准。

public class IpaUtil{

    /**
     * 解压IPA文件,只获取IPA文件的Info.plist文件存储指定位置
     * @param file   zip文件
     * @param unzipDirectory     解压到的目录
     * @throws Exception
     */
    private static File getZipInfo(File file, String unzipDirectory) throws Exception{
        // 定义输入输出流对象
        InputStream input = null;
        OutputStream output = null;
        File result = null;
        File unzipFile = null;
        ZipFile zipFile = null;
        try{
            // 创建zip文件对象
            zipFile = new ZipFile(file);
            // 创建本zip文件解压目录
            String name = file.getName().substring(0, file.getName().lastIndexOf("."));
            unzipFile = new File(unzipDirectory + "/" + name);
            if(unzipFile.exists()){
                unzipFile.delete();
            }
            unzipFile.mkdir();
            // 得到zip文件条目枚举对象
            Enumeration<? extends ZipEntry> zipEnum = zipFile.entries();
            // 定义对象
            ZipEntry entry = null;
            String entryName = null;
            String names[] = null;
            int length;
            // 循环读取条目
            while(zipEnum.hasMoreElements()){
                // 得到当前条目
                entry = zipEnum.nextElement();
                entryName = new String(entry.getName());
                // 用/分隔条目名称
                names = entryName.split("\\/");
                length = names.length;
                for(int v = 0; v < length; v++){
                    if(entryName.endsWith(".app/Info.plist")){ // 为Info.plist文件,则输出到文件
                        input = zipFile.getInputStream(entry);
                        result = new File(unzipFile.getAbsolutePath() + "/Info.plist");
                        output = new FileOutputStream(result);
                        byte[] buffer = new byte[1024 * 8];
                        int readLen = 0;
                        while((readLen = input.read(buffer, 0, 1024 * 8)) != -1){
                            output.write(buffer, 0, readLen);
                        }
                        break;
                    }
                }
            }
        }
        catch(Exception ex){
            ex.printStackTrace();
        }
        finally{
            if(input != null){
                input.close();
            }
            if(output != null){
                output.flush();
                output.close();
            }
            // 必须关流,否则文件无法删除
            if(zipFile != null){
                zipFile.close();
            }
        }
        
        // 如果有必要删除多余的文件
        if(file.exists()){
            file.delete();
        }
        return result;
    }

    /**
     * IPA文件的拷贝,把一个IPA文件复制为Zip文件,同时返回Info.plist文件 参数 oldfile 为 IPA文件
     */
    private static File getIpaInfo(File oldfile) throws IOException{
        try{
            int byteread = 0;
            String filename = oldfile.getAbsolutePath().replaceAll(".ipa", ".zip");
            File newfile = new File(filename);
            if(oldfile.exists()){
                // 创建一个Zip文件
                InputStream inStream = new FileInputStream(oldfile);
                FileOutputStream fs = new FileOutputStream(newfile);
                byte[] buffer = new byte[1444];
                while((byteread = inStream.read(buffer)) != -1){
                    fs.write(buffer, 0, byteread);
                }
                if(inStream != null){
                    inStream.close();
                }
                if(fs != null){
                    fs.close();
                }
                // 解析Zip文件
                return getZipInfo(newfile, newfile.getParent());
            }
        }
        catch(Exception e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 通过IPA文件获取Info信息
     */
    public static Map<String, String> getVersionInfo(File ipa) throws Exception{

        File file = getIpaInfo(ipa);
	Map<String,String> map = new HashMap<String,String>();
	// 需要第三方jar包dd-plist 
	NSDictionary rootDict = (NSDictionary)PropertyListParser.parse(file); 
	// 应用包名 NSString parameters = (NSString)rootDict.objectForKey("CFBundleIdentifier"); 
	map.put("CFBundleIdentifier", parameters.toString()); 
	// 应用名称 NSString parameters = (NSString)rootDict.objectForKey("CFBundleName");
        map.put("CFBundleName", parameters.toString());
	// 应用版本 parameters = (NSString)rootDict.objectForKey("CFBundleVersion");
        map.put("CFBundleVersion", parameters.toString());
	// 应用展示的名称 parameters = (NSString)rootDict.objectForKey("CFBundleDisplayName"); 
	map.put("CFBundleDisplayName", parameters.toString()); 
	// 应用所需IOS最低版本 parameters = (NSString)rootDict.objectForKey("MinimumOSVersion"); 
	map.put("MinimumOSVersion", parameters.toString()); 

	// 如果有必要,应该删除解压的结果文件
	file.delete(); 
	file.getParentFile().delete(); 
				
	return info; 
    }
}





如果用Maven,可以在pom文件中加入如下xml,获取到第三方包dd-plist:

<dependency>
	<groupId>com.googlecode.plist</groupId>
	<artifactId>dd-plist</artifactId>
	<version>1.16</version>
</dependency>
如果想直接获取到此jar包,可以在此处下载:http://download.csdn.net/detail/ruyi366/9149741



2017-03-23 10:51:23 u012198553 阅读数 11566

最近有需求需要在打好包的ipa内添加配置文件,由程序读取配置到程序内,因此做了需求调研,最后找到一个方法,现在说明如下:

一、ipa压缩包结构说明

这里写图片描述

将ipa解压得到包里的内容如下:
1、_CodeSignature
文件hash列表:存放每个文件的hash值;
2、—–.xcent
授权文件:存放App有哪些权限被允许;
3、—-.mobileprovision
配置文件:存放证书及其它一些相关项目;
4、其它-一些资源文件

由于iOS在打包的过程中会对程序包内的每个文件都做签名,在程序包内的文件是不允许被修改的,否则再次打包就会无法安装;
在里面可以存放“空文件夹”,这样系统就会认为没有变化,再次打包安装是没问题的;

//注意:
//这个里面的其他位置是无法放置其它文件的,但是在_CodeSignature文件夹内可以添加其它文件,iOS系统是不会校验这个文件夹内多余的文件的;
//这样就可以在ipa打包之后,实现动态的在ipa包内添加工程的相关配置;

二、ipa包内文件的访问

iOS应用都被限制在“沙盒”中,“沙盒”相当于一个加了仅主人可见权限的文件夹,苹果对沙盒有以下几条限制。
    (1)、应用程序可以在自己的沙盒里运作,但是不能访问任何其他应用程序的沙盒。
    (2)、应用程序间不能共享数据,沙盒里的文件不能被复制到其他应用程序文件夹中,也不能把其他应用程序文件夹中的文件复制到沙盒里。
    (3)、苹果禁止任何读、写沙盒以外的文件,禁止应用程序将内容写到沙盒以外的文件夹中。
    (4)、沙盒根目录里有三个文件夹:Documents,一般应该把应用程序的数据文件存到这个文件夹里,用于存储用
沙盒就是应用程序的安装过程中、系统为每个单独的应用程序生成它的主目录和一些关键的子目录  —文件夹
沙盒机制是一种安全体系,它规定了应用程序只能在本应用程序沙盒中读取文件,不可以访问其他地方的内容。所有的非代码文件都保存在这个地方,比如图片、音频、视频、属性列表(偏好设置)和文本文件等。
优点 安全 每个应用程序都在自己的沙盒内 不能随意跨越自己的沙盒区访问别的应用程序沙盒的内容,应用程序向外请求或接受数据都需要经过权限认证
缺点 文件访问受限 访问文件不灵活


获取这些目录路径的方法:
1,获取home目录路径的函数:
NSString *homeDir = NSHomeDirectory();
2,获取Documents目录路径的方法:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
3,获取Caches目录路径的方法:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachesDir = [paths objectAtIndex:0];
4,获取tmp目录路径的方法:
NSString *tmpDir = NSTemporaryDirectory();
5,获取应用程序程序包中资源文件路径的方法:
例如获取程序包中一个图片资源(apple.png)路径的方法:
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@”apple” ofType:@”png”];
UIImage *appleImage = [[UIImage alloc] initWithContentsOfFile:imagePath];
代码中的mainBundle类方法用于返回一个代表应用程序包的对象。

三、_CodeSignature文件的读取

1、路径文件读取

 //资源包路径    
  NSString *bunPath = [[NSBundle mainBundle]bundlePath];
   //获取资源包下所有文件的子路径
    NSArray *pathArray = [[NSFileManager defaultManager]subpathsAtPath:bunPath];
    //拼接CodeResources路径
    NSString *codePath = [bunPath stringByAppendingPathComponent:@"_CodeSignature/CodeResources"];
    //数据读取
    NSData *data = [NSData dataWithContentsOfFile:codePath];

2、虽然可以解压ipa,在里面放置文件,但是不能通过程序往里面写入数据,这是不被允许的;

Error Domain=NSCocoaErrorDomain Code=513 "The operation couldn’t be completed. (Cocoa error 513.)" UserInfo=0x17407bf00 {NSFilePath=/private/var/mobile/Containers/Bundle/Application/C30F8A79-A9B0-4907-A528-070110717701/f.app/_CodeSignature, NSUnderlyingError=0x17405dd90 "The operation couldn’t be completed. Operation not permitted"}
2016-09-28 22:49:15 u012988591 阅读数 6513

iOS ipa重签名 (个人版、企业版APP均可)

下面是个人之前使用过的方式,介绍比较详细

注意: 在开始重签之前你先要有一个企业证书或者个人开发者证书(个人或者公司均可)(苹果开发证书)

重签名:可以让用个人开发者账号打出来的包,不用上架Appstore即可将其安装到iOS设备上(前提条件是你得有一个开发者证书)。
风险提示:这种重签名方法仅供个人有兴趣的开发者去玩玩,不提倡用于商用,提倡使用Appstore上传发布到你的应用,重签名只能算是黑科技,苹果所不提倡的东西,如果APP使用量过大的话,企业证书有被封停的风险。当然,如果你使用的是个人开发者账号,则只能在添加了UUID的设备上面安装

苹果在iOS8.1.3系统以后加强了对ipa安装包签名的验证,主要区别在于ipa唯一标识在原有Bundle Identifier的基础上增加了证书ID,也就说安装包和手机上已安装APP的Bundle Identifier即使一致,如果两者签名的证书ID不相同,那么安装包也无法正常安装。

钥匙串中的证书列表

图中方框里字符串就是证书ID(钥匙串中我的证书),升级后的ipa标识就是证书ID+BundleID,只有两者完全匹配,安装包才能覆盖安装,否则就会提示安装失败。解决办法就是卸载安装包,重新安装!
如果这个地方找不到证书ID,可登录到苹果开发者中心https://developer.apple.com,memberCenter,点击certificates,identifier&Profiles,再点击identifier中的App IDs点击某个AppId(因为证书ID是唯一的,所以选哪个APPID都是一样的)

证书ID
其中Prefix就是证书ID

目前,重签名主要用于企业证书重签名个人证书发布的ipa包,包括各种助手及企业内测包的发布等。在重签名前,让我们先看看一个完整的ipa包有哪些与证书相关的东西!将ipa包后缀名改为zip,解压之后,会发现一个文件夹Payload(如果是个人证书打包还会包含Symbols文件夹),payload文件夹下面的XXX.app文件夹中有_CodeSignature签名文件夹和embedded.mobileprovision证书配置文件以及其他资源文件。重签名只关注这两个文件即可。

重要文件

_CodeSignature -> ipa包签名文件
embedded.mobileprovision -> 证书配置文件
so,替换上面两个文件就解决了ipa重签名的主要问题。
替换_CodeSignature里面的签名文件需要用到一个文件entitlements.plist的授权文件。所以我们要创建一个entitlements.plist文件,具体格式如下:

plist文件如图所示

xml格式如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>application-identifier</key>
        <string>xxxxxxxxxx.com.xxx.xxx</string>
        <key>com.apple.developer.team-identifier</key>
        <string>xxxxxxxxxx</string>
        <key>get-task-allow</key>
        <false/>
        <key>keychain-access-groups</key>
        <array>
            <string>xxxxxxxxxx.com.xxx.xxx</string>
        </array>
    </dict>
</plist>

其中xxxxxxxxxx.com.xxx.xxx要换成ipa标识(就是证书ID+BundleID),其中xxxxxxxxxx就是你的证书ID,后面部分是bundleID
注意:get-task-allow一定要填NO(false)(否则安装一定失败),还有bundleID一定要与新的embedded.mobileprovision相对应,不然会导致签名失败。
准备工作都做好了 ,是开始我们重签名的真正的步骤了:
1、解压你所要签名的ipa包(解压后里面包含Payload(如果是个人证书打包还会包含Symbols文件夹))
unzip xxx.ipa
2、删除Payload中xxx.app里面的_CodeSignature文件夹
rm -rf Payload/xxx.app/_CodeSignature
3、拷贝embedded.mobileprovision(新的必须改名为embedded)到Payloadxxx.app里面
cp embedded.mobileprovision Payload/xxx.app
4、创建entitlements.plist,并用该文件进行重签名
codesign -f -s "iPhone Distribution: xxxxxxxxxx" --entitlements entitlements.plist Payload/xxx.app
其中"iPhone Distribution: xxxxxxxxxx"是证书名, 在钥匙串中能找到
5、修改xxx.app下面的info.plist里面的bundleIdentifier为你自己的bundleIdentifier
6、打包
zip -r xxx.ipa Payload(如果之前文件夹包含Symbols文件夹,该文件夹与Payload文件夹一起打包)
7、安装到手机进行验证
xcode、iTunes、各种手机助手、或者一些第三方托管平台(比如蒲公英等)

codesign命令
1. 重签名
    codesign -f -s "iPhone Distribution: xxxxxxxxxx" --entitlements entitlements.plist Payload/xxx.app
2. 查看当前MAC电脑中的安装的开发者证书:
     security find-identity -v -p codesigning
3. 查看签名信息
     codesign -vv -d Payload/xxx.app
     可以看到如下信息:

查看签名信息


    identifier                   ———>bundleID
    iPhone Distribution :XXX     ———>证书名
    TeamIdentifier               ———>证书ID(即 App ID Prefix4. 验证签名是否成功
     codesign —verify Payload/xxx.app

验证签名成功与否

我自己这边看到的结果是这样的,重签名是成功的。

PS: !!!
如果你的APP中使用到了keychains的存取,APP在写入keychains时报错并导致APP奔溃日志:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Couldn't add the Keychain Item.
导致crash的原因是keychains的数据仅共享于同公司(企业账号),别的公司(账号)访问不了你公司产品的keychain,所以重签名的bundeID必须与原来的一致。即你重签名所用的entitlements.plist中的bundleID要与原待签名的APP的bundleID一致。
下面两种做法均可以避免改问题
1、直接在Payload/xxx.app/info.plist中修改bundle identifier为与entitlements.plist中配置的bundleID一致
2、如果你不想改变你的bundleID,在你重签名所用到的企业证书需要去配置一个新的AppID,对该AppID配置App ID Suffix(Bundle ID)为待签名的App的bundleID,根据这个appID重新创建发布文件.mobileProversion文件。

如有疑问,可联系m12860gyh@gmail.com或者在下面留言
参考:
点击查看参考1
点击查看参考2

2016-06-01 15:02:11 shengdaVolleyball 阅读数 1662

今天上午的时候已经说过如何通过Xcode和iTunes打包测试程序,现在就来说说打包好的测试包如何安装到手机吧

iOS怎么安装ipa文件?ipa格式的程序文件,可能是一些破解类的软件游戏,或者是一些内测版本的软件。现在我们来分享一个iOS安装ipa格式文件的详细方法。

iOS安装ipa文件的两种方法教程

  ipa文件的安装方法有两种,一种是使用iTunes安装,另外一种是使用第三方软件安装。

一、ipa文件是苹果iTunes能够识别的软件,直接把它拖动到iTunes里面,(或者打开itunes-点击左上角的文件-添加文件),然后连接你的iOS设备,这样iTunes就可以识别到你的应用程序,然后应用就可以了(同步也可以,但是我没用过)。
1、添加ipa文件到iTunes中
  这里写图片描述

2、这里写图片描述

删除iTunes中的 ipa的方法是点击用户–>账号信息管理 –> 我的应用,然后选中右键有删除

二、下面再具体介绍一下使用第三方软件安装ipa文件的方法。首先请确定你的iPhone已经越狱了,然后我们可以通过第三方工具软件,如PP助手、iTools 之类的来安装ipa格式文件。

  具体方法步骤如下:

  1、这里以PP助手为例,先把iPhone用原装数据线连接电脑,打开PP助手,点击左侧的iPhone一栏,会在右窗格中看到机器的相关信息,可以看到是否越狱一栏显示“是”,如图所示。
  这里写图片描述

 2、接下来请点击左侧的“程序库”栏目,如图所示。
这里写图片描述

3、在右边的程序库中,点击上方的“添加”按钮,如图所示。
这里写图片描述

 4、然后在文件选择框中,选择我们想要安装在iPhone的ipa文件,如图所示。
 这里写图片描述

5、把ipa文件添加到PP助手的程序库以后,接下来请点击“安装”按钮,就可以把这个文件安装到iPhone上了。
这里写图片描述

第三方的方法是从网上找来的,并没没有实测经验。如果具备条件的话还是使用iTunes进行安装,方便。

iOS打包ipa

阅读数 387

ios ipa文件分析

阅读数 779

iOS打包IPA文件

阅读数 495

iOS打包成 ipa包

阅读数 243

iOS 打包ipa

博文 来自: chermon_love15
没有更多推荐了,返回首页