構建Potatso問題集錦及解決方案

轉載請註明文章出處:https://tlanyan.me/build-pota...

前言

半年前寫過一篇構建自用Shadowsocks客戶端Potatso的教程“構建自己的iOS網絡代理客戶端”。當時除libYAML依賴下載不正常外,編譯測試使用全過程都很順利。文章投遞到幾個平臺被數萬網友圍觀,不少網友根據教程在構建時遇到各種問題。最初我以爲是網友看教程不仔細或構建環境差異造成,沒多注意。後來陸續有網友加我QQ,讓我懷疑寫完文章後代碼有了重大更新。

終於在昨天(除夕)抽出時間,用最新版的代碼構建Potatso並安裝到我最新版iOS系統的iPad上。這個過程花費了幾個小時,覆蓋了許多網友諮詢我的問題,本文中將一一給出解決方案。

如果你的Xcode版本是9.4.1,使用commitID爲318a5e1的代碼,根據“構建自己的iOS網絡代理客戶端”中的教程可以順利的編譯和安裝Potatso到iOS12系統以下的設備。如果你的設備升級到了最新版,或者遇到其他問題,請繼續閱讀本文。

爲什麼執着於構建自用Shadowsocks客戶端?由於iOS生態的封閉性,正常情況下只能通過App Store下載應用。應用下架後,會導致手機重置、購買買新設備後無法安裝。安卓、Windows、MacOS則不會有這個問題,只要安裝文件存在,總是有得用。所以針對iOS設備構建自用的客戶端很有必要,尤其是SS這類隨時有可能下架的應用。

本文構建Potatso客戶端最終得工程文件以及生成的ipa包已上傳到百度雲盤:https://pan.baidu.com/s/1twyM...

如果構建過程中遇到本文列出以外的問題,歡迎留言或加Q羣688196496

構建步驟

這節簡要回顧構建Potatso的流程:

1. 安裝Cocospods

如果已安裝,請略過此步。

  1. 更新系統的gem版本:打開終端,輸入:sudo gem update --system
  2. 設置國內gem源:gem sources --list輸出爲https://gems.ruby-china.org/請略過此步;否則先刪除官方源再添加gems國內源:gem sources --remove https://rubygems.org/; gem sources --add https://gems.ruby-china.org/
  3. 安裝Cocospods:sudo gem install cocoapods

2. 構建Potatso

構建Potatso的步驟如下:

  1. 克隆代碼:git clone https://github.com/haxpor/Potatso.git
  2. 更新子模塊:cd Potatso; git submodule update --init
  3. 安裝依賴:打開Podfile,將第一行改成:source 'https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git'(使用清華的CocoaPods源),然後運行pod install --verbose
  4. 使用XCode打開Potatso.xcworkspace
  5. 更改PotatsoPacketTunnelTodayWidget兩個子項目的Bundle ID,例如本人分別改成:potatso.tlanyan.mepotatso.tlanyan.me.PacketTunnelpotatso.tlanyan.me.TodayWidget
  6. 更改PotatsoPacketTunnelTodayWidget兩個子項目Capabilities中的App GroupKeychain Sharing的Group:在"App Groups"中刪除原有的group.io.wasin.potatso,新增自己的group,例如:"group.potatso.tlanyan.me";在"Keychain Sharing"中輸入自己的group ID;
  7. 打開"PotatsoBase/Potatso.m"文件,將shareGroupIdentifier函數的返回值改成自己的group id;
  8. 將iPhone等iOS設備連接到電腦,目標選擇新接入的設備,點擊左上角的“build and run”按鈕,Xcode會編譯並安裝App到設備上,然後啓動。

可能遇到的問題

昨天幾個小時的折騰,遇到的十來個問題。下文將一一列出,並給出解決方案。構建過程中你可能會遇到不止一個錯誤,請根據錯誤信息按Ctrl + F在本文查找。如果遇到其他問題,歡迎留言或加Q羣688196496

1. the sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocosPods installation.

問題截圖

error2.png

原因: pod依賴未安裝

解決辦法: 安裝依賴,執行命令:pod install --verbose

2. url: (7) Failed to connect to pyyaml.org port 80: Connection refused

錯誤描述: 執行pod install,前面一切順利,到libYAML會出現問題:

Installing LibYAML (0.1.4)

[!] Error installing LibYAML
[!] /usr/bin/curl -f -L -o /var/folders/dj/ljst94xx47l7fn3wz4q9bwsw0000gn/T/d20180822-4467-1cotycr/file.tgz http://pyyaml.org/download/libyaml/yaml-0.1.4.tar.gz --create-dirs --netrc-optional --retry 2

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
 curl: (7) Failed to connect to pyyaml.org port 80: Connection refused

原因: libYAML的官網關閉了80端口訪問

解決辦法: 編輯" /Users/你的用戶名/.cocoapods/repos/master/Specs/5/b/9/LibYAML/0.1.4/LibYAML.podspec.json"文件,將"http://pyyaml.org/download/libyaml/yaml-0.1.4.tar.gz"改成“https://pyyaml.org/download/l...

備註: 此解決方案來自貌似LibYAML官方人員的回覆,親測可以。當然可以使用前文“構建自己的iOS網絡代理客戶端”中所說的網絡劫持方法。

3. Diff:/Podfile.lock: No such file or directory

使用新版代碼並安裝好依賴後,這應該是構建過程中最先出現的問題。

問題截圖:

error1.png

原因:根據錯誤描述跟蹤腳本執行流程,發現是執行預構建腳本時SRCROOT環境變量的值無法獲取(或被錯誤置爲空)導致。

解決方案: 嘗試過更改構建時生成的臨時腳本文件、注入全局環境變量等,這些方法均不湊效。後來通過diff發現腳本由文件Potatso.xcodeproj/project.pbxproj文件中的配置生成,該文件在pod install後被修改。解決辦法很簡單:還原更改。執行完pod install命令後,執行git checkout Potatso.xcodeproj/project.pbxproj,問題解決。

4. No podspec found for CallbackURLKit in ./Library/CallbackURLKit

問題截圖:

error3-1024x143.png

原因: 子模塊的代碼未下載

解決方案: 初始化子模塊代碼,執行命令:git submodule update --init

5. The operation couldn't be completed. Unable to log in with account 'xxxx'. The login details for account 'xxxx' / No profiles for 'xxxx' were found: Xcode couldn't find any iOS App Development provisioning profiles matching 'xxx' / Code signing is required for product type...

問題截圖:

error4.png

原因: Apple ID過期未續費

解決方案: Apple ID續費或換其他可用的ID

6. No account for team 'xxx'. Add a new account in the Accounts preference pane or verify that your accounts have valid...

錯誤信息基本與上一條相同,只是賬號換成了team ID。

問題截圖:

error7.png

原因: team ID不在已添加的賬號內

解決方案: 在屬性頁面的Team中選擇自己的賬號

7. Your account does not have sufficient permissions to modify containers. / No profiles for 'xxxx' were found

問題截圖:
error5.png

原因: 該Bundle ID已經被其他Apple ID使用

解決方案: 換一個新的

8. An Application Group with Identifier 'xxxx' is not available. Please enter a different string.

問題截圖:
error6.png

原因: Group ID已經被其他Apple ID使用

解決方案: 用一個新的

9. Module 'Crashlytics' not found

這個錯誤未截圖。

原因: Podfile文件裏沒有加這個庫

解決方案: 打開Podfile,在def library中添加一行:pod 'Crashlytics', '~> 3.10.7',然後執行pod install --verbose

備註: 該解決方案參考Github的issue: https://github.com/haxpor/Pot...。注意pod安裝依賴後,會更改Potatso.xcodeproj/project.pbxproj文件,直接編譯會出現第二個問題。正確操作應當如下:先備份Potatso.xcodeproj/project.pbxproj文件,然後執行pod install --verbose,成功後將文件覆蓋。後續出現pod依賴更新的情況也應該按此步驟操作。

10. Could not locate device support files

問題截圖:

error9.png

原因: Xcode版本過低,不支持iOS 12.1系統。根據官方頁面,需要Xcode 10

error9-1.png

解決方案: 安裝Xcode 10,文件較大,根據網速需要一定時間,請耐心等待

11. Invalid redeclaration of '<-' EnumOprators.swift

問題截圖:

error10.png

原因: ObjectMapper的版本過低

解決辦法: 使用新版的ObjectMapper:打開Podfile,將ObjectMapper那一行改成pod 'AlamofireObjectMapper', '~> 5.0'

備註: 解決方案參考https://stackoverflow.com/que...

12. Type 'RLMIterator<proxy>' does not conform to protocol 'Sequence'</proxy>

問題截圖:

error11.png

error11-1-1024x406.png

原因: 這個問題不清楚具體原因。懷疑是Realm這個庫的問題,沒有實現Sequence接口。我將RealmSwift改到最新的3.7.6問題亦沒有解決。不懂Swift,不過感覺是RMLIterator或者Proxy/RuleSet等存在問題。

解決辦法: 註銷PotatsoMode/DBUtils.swift中的相關代碼,具體是174-190和202-218行之間的代碼。

備註: 解決方案來自:https://github.com/haxpor/Pot...。所有錯誤中,只有這個錯誤不是完美解決。

13. Initializer for conditional binding must have Optional type, not '[Rule]'

問題截圖:

error12.png

原因: 非nil值不應該使用if let(我自己的理解,畢竟不懂Swift)

解決辦法:Potatso/Core/API.swift第65和256行的if和大括號去掉,65行修改示意:

<pre>// 修改前
// if let parsedObject = Mapper<Rule>().mapArray(JSONArray: rulesJSON as! [[String : Any]]){
// let parsedObject = Mapper<Rule>().mapArray(JSONArray: rulesJSON as! [[String : Any]])
// rules.append(contentsOf: parsedObject)
//}
// 修改後
let parsedObject = Mapper<Rule>().mapArray(JSONArray: rulesJSON as! [[String : Any]])
rules.append(contentsOf: parsedObject)
</pre>

備註: 解決辦法的靈感來自:https://stackoverflow.com/que...。當然這個問題和Potatso無關。

還有一個錯誤截圖:

error10-1.png

具體什麼忘了。如果你遇到了或者有解決方案,可留言告訴我。

參考

  1. 構建自己的iOS網絡代理客戶端
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章