Xcode 4.1/4.2/4.2.1 免證書(iDP)開發+真機調試+生成IPA全攻略

開發環境使用的是目前爲止最新的穩定版軟件:Mac OS X Lion 10.7 + Xcode 4.1
目前Xcode 4.2 Preview版也已經發布,據說其修改方法跟4.1非常類似,只改動了一行代碼,請參看參考文章的第二篇。本文仍以4.1版本爲例。
更新:現在Xcode 4.2正式版和iOS 5均已發佈,下面補充上4.2的修改方法。(2011-10-24)
各步驟會標明版本,比如(Xcode4.1請執行)和(Xcode4.2請執行),4.2.1的修改方法與4.2完全相同
未標明的步驟爲兩個版本均需執行的步驟!

2012年1月27日更新:
目前本人已經測試並證實有效的平臺有
Xcode 4.1:
iPod touch 4 iOS 4.3.3

Xcode 4.2:
iPod touch 4 iOS 4.3.3
iPod touch 4 iOS 5.0
iPod touch 4 iOS 5.0.1

Xcode 4.2.1:
iPod touch 4 iOS 4.3.3
iPod touch 4 iOS 5.0.1
iPhone 4S iOS 5.0.1(5A406)

另外,操作系統的版本貌似對調試影響不大,這期間用過的系統有Mac OS X 10.7~10.7.2,都沒有問題。

當然您需要先越獄您的設備並通過Cydia安裝AppSync
本文參考了多篇文章,綜合其中的方法,並修正其中的錯誤,整理而成。
未經許可,請勿轉載。本文首次發表於http://kqwd.blog.163.com/
參考的文章有:
http://laolang.cn/back-end-develop/helloworld-iphone-developer.html
http://ccmos.tw/blog/2011/06/30/xcode4-port-program-to-idevice-without-idp/
http://www.cnblogs.com/flyingzl/articles/2207717.html

衆所周知,在Xcode上開發的程序只能在模擬器中運行,如果要放到真機上則要花費99美金購買開發者證書iDP。這嚴重阻礙了我等草根開發者探索的腳步。寫個小程序,同學間分享一下這個小小的願望都不能滿足,自然不能善罷甘休。
在沒有iDP的情況下,要想將程序放到iPhone上調試,並最終發佈IPA用於分享,需要以下幾個步驟:
1.自己爲自己頒發一個證書用於爲生成的程序簽名
2.修改工程配置以及Xcode的配置文件和二進制文件以阻止其驗證和簽名
3.通過自定義生成步驟,用僞造的證書爲應用程序簽名
4.使用一點小trick來生成IPA文件

開始之前的友情提示:
1. 本文給有一定基礎的朋友看,各種命令是免不了的。UNIX中的基本命令比如cp,mv,cd,chmod,sudo啥的還有vim編輯器,如果您都沒聽說過,強烈建議您不要嘗試本文提到的修改。一旦改錯了輕則Xcode掛掉,重則系統崩潰。
2. 本文的每一個步驟都是必須的,如果您哪一步沒有得到預期的結果,請不要繼續,以免發生更加意外的事情。。。
3. 如果遇到解決不了的問題歡迎留言詢問,務必給出詳細的錯誤信息,否則無法判斷。博主恕不解答類似於如何執行腳本代碼,如何賦予執行權限,如何使用vim編輯器(如何保存)等與iOS開發無關的UNIX基礎問題。

1.創建證書
創建證書的過程比較簡單,打開實用工具-鑰匙串訪問。然後在菜單欄裏點擊鑰匙串訪問-證書助理-創建證書來打開向導。第一個步驟比較重要,必須要把名稱命名爲iPhone Developer,將類型設定爲代碼簽名,將"讓我覆蓋這些默認值"選中。之後的步驟無需更改,一路點擊“確定”和“繼續”來完成這個嚮導就可以。
Xcode 4.1免證書(iDP)開發+真機調試+生成IPA全攻略 - 月下獨酌 - 錦瑟華年

2.修改Xcode的配置文件和二進制文件
下面的步驟稍微有點繁瑣,您應該瞭解UNIX命令行的基本操作,並瞭解一種命令行文本編輯器,本文使用的是vim。儘管這裏會給出完整的代碼,但是關於修改和保存代碼的基本操作,不再贅述。下面的操作請先將Xcode按Command+Q完全關閉
(1)修改配置文件
進入目錄並備份原文件(4.1和4.2在這裏主要的差別是SDK的目錄名不同)
(Xcode4.1請執行)cd /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/
(Xcode4.2請執行)cd /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/
sudo cp SDKSettings.plist SDKSettings.plist.orig
進行編輯
sudo vim SDKSettings.plist
將以下兩段中的YES改爲NO
<key>CODE_SIGNING_REQUIRED</key>
<string>YES</string>
<key>ENTITLEMENTS_REQUIRED</key>
<string>YES</string>

下面修改另外一個文件
進入目錄並備份原文件
cd /Developer/Platforms/iPhoneOS.platform/
sudo cp Info.plist Info.plist.orig
進行編輯
sudo vi Info.plist
將全部的XCiPhoneOSCodeSignContext 修改成 XCCodeSignContext,網上的大部分文章說有2處,但我找到了3處,可能是Xcode 4.1要多一處?(Xcode 4.2也有三處)總之都改掉了。提示:在在vim中輸入/要搜索的內容來搜索,按n鍵是搜索下一處。

(2)二進制補丁
#在桌面上建立script這個腳本
cd ~/Desktop
vim script
#(Xcode 4.1執行)在編輯器中輸入如下內容
#!/bin/bash
cd /Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Plug-ins/iPhoneOS\ Build\ System\ Support.xcplugin/Contents/MacOS/
dd if=iPhoneOS\ Build\ System\ Support of=working bs=500 count=255
printf "xc3x26x00x00" >> working
/bin/mv -n iPhoneOS\ Build\ System\ Support iPhoneOS\ Build\ System\ Support.original
/bin/mv working iPhoneOS\ Build\ System\ Support
chmod a+x iPhoneOS\ Build\ System\ Support
#(Xcode 4.2執行)在編輯器中輸入如下內容
#!/bin/bash
cd /Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/PrivatePlugIns/iPhoneOS\ Build\ System\ Support.xcplugin/Contents/MacOS/
dd if=iPhoneOS\ Build\ System\ Support of=working bs=500 count=255
printf "xc3x26x00x00" >> working
/bin/mv -n iPhoneOS\ Build\ System\ Support iPhoneOS\ Build\ System\ Support.original
/bin/mv working iPhoneOS\ Build\ System\ Support
chmod a+x iPhoneOS\ Build\ System\ Support
保存並退出。(4.1和4.2在這裏的區別也是目錄名不同,就是代碼中綠色的部分。4.1是Plug-ins而4.2是PrivatePlugIns
授予這個腳本執行權限並執行它
chmod 777 script
./script
正常的話應該輸出(具體的數字可能有差別)
231+1 records in
231+1 records out
115904 bytes transferred in 0.001738 secs (66694555 bytes/sec)
至此,對SDK中配置文件和二進制文件的修改就完成了

3.準備自定義的生成後腳本
連接互聯網後執行
mkdir /Developer/iphoneentitlements401
cd /Developer/iphoneentitlements401
curl -O http://www.alexwhittemore.com/iphone/gen_entitlements.txt
mv gen_entitlements.txt gen_entitlements.py
chmod 777 gen_entitlements.py
如果您已經聯網,則請直接轉到步驟4,如果您沒有聯網,那麼請手動創建/Developer/iphoneentitlements401/gen_entitlements.py並授予其執行權限,這個文件的內容爲
#!/usr/bin/env python

import sys
import struct

if len(sys.argv) != 3:
print "Usage: %s appname dest_file.xcent" % sys.argv[0]
sys.exit(-1)

APPNAME = sys.argv[1]
DEST = sys.argv[2]

if not DEST.endswith('.xml') and not DEST.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/>
</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()

4.修改工程設置
特別注意:本階段之前的修改配置文件、準備腳本等,只需要做一次。但本階段的操作,對每個需要真機調試的工程都要做一遍。
這個步驟的主要作用是支持真機調試,如果不做這個步驟,仍然可以通過步驟5來生成ipa在真機上運行,但是無法使用Xcode內置的調試器對在真機上運行的程序進行單步跟蹤。如果您的程序在點擊Run真機調試時秒退,請檢查此步驟是否正確完成。
 (1)禁用Xcode自動的簽名操作
將工程配置中所有的Code Signing選項全部設爲Don't Code Sign,如圖。可能需要先點擊“All”讓這個選項顯示出來
Xcode 4.1免證書(iDP)開發+真機調試+生成IPA全攻略 - 月下獨酌 - 錦瑟華年
 
(2)添加自定義的生成後腳本
在Build Phases中添加一個Phase,右下角的Add Build Phase,然後單擊Add Run Script,輸入以下腳本
export CODESIGN_ALLOCATE=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate
if [ "${PLATFORM_NAME}" == "iphoneos" ] || [ "${PLATFORM_NAME}" == "ipados" ]; then
/Developer/iphoneentitlements401/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
如圖所示:
Xcode 4.1免證書(iDP)開發+真機調試+生成IPA全攻略 - 月下獨酌 - 錦瑟華年
 
至此配置全部完成,下面就可以插上iPhone,重新選擇生成目標來測試一下在線調試了!如果是第一次使用該設備調試,請先在Organizer中將設備切換爲開發模式,具體操作請見常見問題5。

5.旁門左道生成IPA文件
如果我的程序調試好了,怎麼才能發給別人用呢?正常情況下IPA文件是從Xcode的Organizer中輸出的,但是我們沒有證書,這樣輸出會產生錯誤。我們只能用個小trick來完成這個操作了。
先將代碼生成爲Release目標,然後打開工程的輸出文件夾,通常情況下這個目錄是
/Users/你都用戶名/Library/Developer/Xcode/DerivedData/以工程名打頭的文件夾/Build/Products/Release-iphoneos
很糾結吧~這個目錄下有個.app的文件,就是生成的程序了。把這個.app拖到iTunes中,它會出現在應用程序那個列表中,然後再把它從iTunes的那個列表中拖出來(比如拖到桌面),發生了什麼?哈哈,它就這樣變成.ipa了!
把這個.ipa發給朋友,大家就可以跟您一起分享這個程序了。

文章發表以來點擊量已經超過了5000次,也收到了不少熱心博友的反饋和疑問。現加以整理,列爲常見問題。感謝大家的關注!(2011年12月2日)
常見問題:
不成功的先看這裏!!本文點擊量超過6000,無數網友親測成功,如果您失敗了基本可以確定是您沒有嚴格按照文中的方法操作,下面列出常見問題,切望各位朋友提問前先看看!!(2011年12月14日)
1. 程序運行時報錯,或者根本不能通過編譯。錯誤信息類似(感謝博友rinzeng提出)
ARC forbids explicit messsage send of 'release'
'release' is unavailable: not available in automatic reference counting mode
解答:這個錯誤與本文討論的問題無關,即使在模擬器上運行也照樣會報錯。但我願意在這裏予以解答。這個錯誤是由在iOS 5中最新引進的ARC內存管理機製造成的。解決方法有2種,一是不要加release語句。二是在Build Settings中關閉Objective-C Automatic Reference Counting

2. 各種錯誤,錯誤信息中包含“No such file or directory”這句話
解答:錯誤信息的含義非常清楚,就是“沒有這個文件或者目錄”。這類錯誤通常是由於您拷貝代碼時不全或者開發環境安裝錯誤等問題導致的。請再次檢查報錯的目錄是否存在,檢查代碼與本文給出的是否嚴格一致,各種檢查吧~總之是低級錯誤

3. 聯機調試時程序秒退,或者任何時候報錯,錯誤信息中包含“code sign”、“CERT”或者“certificate”字樣的
解答:證書錯誤或者簽名錯誤,這種問題就不要問了,肯定是因爲您沒有嚴格文中的步驟做。提醒您檢查的地方有(1)有沒有設置爲Don't Code signing (2)生成後事件的代碼是否已經正確粘貼 (3)那個Python腳本是否已經成功執行
其中最可能出問題的就是生成後事件代碼(文中的那個Run Script)沒有正確執行。可能是您忘記了添加Run Script並粘貼那段代碼,也可能是您沒複製全,或者複製到了啥特殊字符導致執行出錯。查看那個script的執行結果的方法是在Xcode左側的側邊欄裏,點最靠右的一個標籤(Show the Log navigator),看最近的一個Build日誌(不是Debug日誌),找到一行Run custom shell script "Run Script"那一行,正常情況下那一行跟其他行一樣,是不能展開的。如果那一行左邊有個小箭頭,點擊後能展開的話,說明執行出錯,展開後的信息即爲出錯的信息。請認真查看錯誤信息並修正腳本中的錯誤。如果Build日誌里根本沒有Run custom shell script "Run Script",那說明您忘記添加Build script了。。。(2012年2月9日更新)

4. iPad能用嗎?
解答:我沒有iPad,所以沒法準確回答。但從熱心博友的回覆來看,iPad無疑是可以用的。
如果要用ipad 需要把第四步腳本文件裏的 platform_name == iphones 換成platform_name == ipads 不然會報錯的~ (感謝博友xyishao的建議)
感謝qingcheng89提出的改進意見,現在來看上述代碼可以直接支持iPad而無需修改,請各位朋友測試。(2012年2月9日更新)

5. 爲什麼我的Build for Archiving選項是灰色的?
解答:是因爲您沒有把設備插到電腦上。雖然這個問題挺蠢的,但我曾經也有過這個疑問,哈哈~~ 
經熱心網友xc7296815提醒,設備未開啓開發模式也會導致Build for Archiving不可用,開啓開發模式的方法是:插上設備,點Xcode右上角的Organizer圖標,選中您的設備,在右邊窗口中點擊“Use for Development” (2011年12月25日)

6.我的iOS版本/Xcode版與你的不同,能用嗎?
解答:我只在iPod Touch 4 + iOS 4.3.3 & 5.0 + Xcode 4.1/4.2上測試可用,在iPhone 4和iPad上雖未測試,但根據網友的反饋是可用的。其他環境我沒有測試過,也沒有條件測試,因此當您的環境與我的不同時,別問我可不可用,您可以試一下,然後把結果告訴我,也爲其他的網友提供方便,在此先謝謝您了!

7.真機調試時出現Error launching remote program: failed to get the task for process xxx錯誤(2012年1月26日更新)
解答:我在調試中貌似沒有遇到過這個問題,但是不少網友指出會有這個問題,誰來告訴我什麼情況下會出這個問題呢?如果您遇到了這個問題,請閱讀Apple官方的幫助文檔http://developer.apple.com/library/ios/#qa/qa1710/_index.html
2012年2月1日更新:有網友指出該錯誤是由於權限設置錯誤導致的。由於我使用了跟報錯的那位網友完全相同的環境,而在操作過程中並沒有遇到這個錯誤,所以基本可以確定是您沒有按步驟操作造成的,請您再次檢查整個過程,尤其是熱心網友提出的下載腳本並修改執行權限的部分。
經本人測試,如果該錯誤出現在編譯運行之後,且現象爲設備上的程序閃退,則是由於簽名錯誤導致的,這是由於您沒有嚴格按照上述步驟來做導致的,請參考常見問題3.(2012年2月9日更新)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章