深入解析Xcode无证书编译以及真机调试

从标题就可以看出文章的主要内容了,一个是无证书编译,另外一个则是真机调试。网上关于此类文章很多,但是基本都是抄来抄去的,也没一个详细的说明具体这么做的原因。并且配置的步骤也基本一致,没什么太大的区别。

对于第一部分来说,与网上的内容大体一致,也没什么奇怪的东西。简单的说就是通过修改xcode的配置文件来实现无证书即可编译.app文件。先说第一部分内容,步骤如下:
1. 执行Command+Q来彻底关系Xcode,修改/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer
/SDKs/iPhoneOS7.1.sdk/SDKSettings.plist
将以下两个字段修改为NO:

<key>CODE_SIGNING_REQUIRED</key>
<string>YES</string>
<key>ENTITLEMENTS_REQUIRED</key>
<string>YES</string>

1

2. 修改Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Info.plist将Info.plist中全部的XCiPhoneOSCodeSignContext 修改成 XCCodeSignContext,他们分别在DefaultProperties分支下、OverrideProperties分支下和RuntimeRequirements分支下。如果不进行此步,编译Device Release版本时會报错:
Code Sign error: a valid provisioning profile matching the application’s Identifier ‘com.yourcompany.xxxx’ could not be found
其实到这里文章的第一部分就结束了,此时就可以建立新的项目或者对 原有的项目进行编译了,但是在编译的时候需要将Code Signing下面的签名选项全部设置为Don’t Code Sign

2

如果这个时候将程序直接连接到越狱设备上运行的时候虽然设备上的应用会正常启动,但是在启动之后xcode却会提示启动应用失败。出现这个错误则是由于调试器无法正常的挂在启动的进程,导致进程启动之后启动器却认为进程启动失败了。要修复这个错误其实也很简单,只需要将Entitlement.plist文件写入到ipa中即可。对应的Entitlement.plist内容也非常简单:

< ?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>get-task-allow</key>
	<true></true>
</dict>
</plist>

最关键的就是这个plist中get-task-allow的选项,如果没有这个选项那么也就无法进行调试了。创建该文件之后还剩最后一步,就是将这个plist文件重新写回到ipa文件中,这样就可以进行调试了。网上的脚本比较复杂,基本上都是通过这个python脚本来生成.xcent的一个文件:

#!/usr/bin/env python
import sys
import struct
if len(sys.argv) != 3:
print "Usage: %s appnamedest_file.xcent" % sys.argv[0]
sys.exit(-1)
APPNAME = sys.argv[1]
DEST = sys.argv[2]
if not DEST.endswith('.xml') and notDEST.endswith('.xcent'):
print "Dest must be .xml (for ldid) or.xcent (for codesign)"
sys.exit(-1)
entitlements = """
< ?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>%s</string>
   <key>get-task-allow</key>
    <true></true>
</dict>
</plist>
""" % APPNAME
f = open(DEST,'w')
if DEST.endswith('.xcent'):
f.write("\xfa\xde\x71\x71")
f.write(struct.pack('>L', len(entitlements)+ 8))
f.write(entitlements)
f.close()

生成的文件会多一个application-identifier 字段,这个字段在二进制文件中有无并不影响程序的正常调试。
要想将plist写回到ipa文件中需要用到xcode的codesign工具,切换到xode项目的Build Phases页面,点击菜单的Editor->Add Build Phase->Add Run Script Build Phase添加Run Script,输入如下的内容:

codesign -fs "iPhone Developer" --entitlements="/Users/obaby/Entitlement.plist" "$BUILT_PRODUCTS_DIR/${WRAPPER_NAME}/$TARGETNAME"

参数说明:
“iPhone Developer” 签名用的证书;
“/Users/obaby/Entitlement.plist” 上面的plist对应的路径
“$BUILT_PRODUCTS_DIR/${WRAPPER_NAME}/$TARGETNAME” 生成的app文件
3
这里需要使用KeyChain Access 来创建一个子签名用的证书,这个证书的创建网上说的非常详细了,也就不多少了,不知道怎么创建的可以参考这个链接:http://blog.csdn.net/lsqtzj/article/details/6533049
网上的脚本是下面的内容:

export
CODESIGN_ALLOCATE=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate
if [ "${PLATFORM_NAME}" =="iphoneos" ] || [ "${PLATFORM_NAME}" == "ipados"]; then
/Applications/Xcode.app/Contents/Developer/iphoneentitlements/gen_entitlements.py "my.company.${PROJECT_NAME}" "${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/${PROJECT_NAME}.xcent";
codesign -f -s "iPhone Developer" --entitlements "${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/${PROJECT_NAME}.xcent" "${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/"
fi

这是因为这个脚本要用上文提到的python脚本来创建xcent文件用来签名。我觉得没这个必要,这个脚本多添加的内容并没有太多的用处,我觉得没这个必要,这个脚本多添加的内容并没有太多的用处,并且这个脚本使错误的,最后签名的一行会直接导致签名失败,如果要用请参考上面的签名修改 .所以还是简单的办法,只需要将我提供的那个plist保存为文件,找好目录,然后添加一行bash命令就ok了。此时就可以既可以在模拟器上也可以在真机上进行调试了。
模拟器调试效果:
4
真机调试效果:

5
最后简单的说下如何打包IPA,从项目的Products下找到编译生成的.app文件,打开iTunes,将生成的.app拖到iTunes中,此时iTunes会自动将.app打包成IPA。然后在iTunes中找到文件右键在Finder中显示就可以看到最终的IPA文件了。

PDF下载:http://pan.baidu.com/s/1c0F4bhI

参考:http://iphonedevwiki.net/index.php/Xcode

You may also like

发表评论

电子邮件地址不会被公开。 必填项已用*标注