本文说的网络代理客户端指ShadowSocks(R)客户端,用途你懂的。
本文写作时的环境:MacOS High Sierra 10.13.6,Xcode版本9.4.1,Swift版本4.1.2,所用代码的commitID: 318a5e1.
4. No podspec found for
本文写作时的环境:MacOS High Sierra 10.13.6,Xcode版本9.4.1,Swift版本4.1.2,所用代码的commitID: 318a5e1.
前提条件
构建iOS设备的自用客户端(Potatso),需要两个前提条件:
- 一台装有XCode的MacOS设备;
- 一个可用的苹果开发者账号。
构建步骤
1. 安装Cocospods
如果已安装,请略过此步。
- 更新系统的gem版本:打开终端,输入:
sudo gem update --system; - 设置国内gem源:
gem sources --list输出为https://gems.ruby-china.org/请略过此步;否则先删除官方源再添加gems国内源:gem sources --remove https://rubygems.org/; gem sources --add https://gems.ruby-china.org/; - 安装Cocospods:
sudo gem install cocoapods。
2. 构建Potatso
构建Potatso的步骤如下:
- 克隆代码:
git clone https://github.com/haxpor/Potatso.git; - 更新子模块:
cd Potatso; git submodule update --init; - 安装依赖:打开
Podfile,将第一行改成:source 'https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git'(使用清华的CocoaPods源),然后运行pod install --verbose; - 使用XCode打开
Potatso.xcworkspace; - 更改
Potatso及PacketTunnel、TodayWidget两个子项目的Bundle ID,例如本人分别改成:potatso.tlanyan.me、potatso.tlanyan.me.PacketTunnel和potatso.tlanyan.me.TodayWidget; - 更改
Potatso及PacketTunnel、TodayWidget两个子项目Capabilities中的App Group和Keychain Sharing的Group:在”App Groups”中删除原有的group.io.wasin.potatso,新增自己的group,例如:”group.potatso.tlanyan.me”;在”Keychain Sharing”中输入自己的group ID; - 打开”Potatso.m”文件,将
shareGroupIdentifier函数的返回值改成自己的group id; - 在Potatso项目的
BuildSettings中找Code Signing Entitlements,将”xxxx.entitlements”删除; - 将iPhone等iOS设备连接到电脑,目标选择新接入的设备,点击左上角的“build and run”按钮,Xcode会编译并安装App,然后启动。
一切顺利的话,iOS设备上的客户端能正常使用,接下来可以安装到多个设备上,也可以打包成ipa用iTunes安装到其他已注册设备。
请记住用途为自用,请不要商业使用或者将应用发布到App Store上(并收费)。
可能遇到的问题
本人构建过程中遇到的主要问题是Cocoapods依赖安装。执行
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端口关闭了,将http替换成https发现可以正常下载。libYAML官网这仅支持https,连301跳转机会都不给的骚操作顿时让我有点小蛋疼。用grep搜索工程,没发现可以把http改成https的配置文件存在;对Cocoapods不熟,libYAML的地址不知是否从云端下载下来;打开
Podfile.lock,将版本从”0.1.4″改成其他的,依赖又出问题;无奈之下先将文件下载下来,将其放到”/var/folders/dj/ljst94xx47l7fn3wz4q9bwsw0000gn/T/d20180822-4467-1cotycr/”目录下并改名为”file.tgz”,再次运行pod install --verbose,发现路径每次都不一样,非常蛋疼。
最后的解决方案是采用网络劫持:
- 新开一个终端,进入root模式:
sudo -i; - 创建download/libyaml目录,将下载的文件复制到文件夹:
mkdir -p download/libyaml; mv /Users/tlanyan/Downloads/yaml-0.1.4.tar.gz download/libyaml/; - 将pyyaml.org域名解析指向本地:vim编辑
/etc/hosts文件,增加一行:127.0.0.1 pyyaml.org; - 用Python启动一个静态web服务器,监听80端口:
python -m SimpleHTTPServer 80。
以root身份设置好监听后,在原来终端继续
pod install --verbose,问题解决。
除了依赖问题,其他问题主要是以Bundle ID/group ID的问题,请根据错误提示修改。
有关Potatso
Potatso的作者是
icodesign,祭奠死去的 Potatso 1为作者对Potatso的自述,建议每一个使用Potatso代码的人都看看。
Github上搜”Potatso”,最匹配排名第一的仓库持有者是haxpor(Wasin Thonkaew)。其在仓库README的第一位置建议使用代码的人查看ADHERE_LICENSE.md中的内容。简单来说就是不要直接复制源码然后发布到App Store上.
其他
本人常用的客户端是
SsrConnectPro,可惜不管全局还是系统代理,都无法使用TG。后来用了WaterDrop,使用TG无忧。遗憾的是前两周WaterDrop抽风,连接服务器后又立马断开,原因未知。想着重装一下就好了,就将其卸载掉。打开App Store搜索发现软件不见踪影,上网查方知已经下架(其他区也下架),只好寻找替代品。在App Store下载了多个客户端,能上外网的很多,用得了Telegram的很少。这顿时让我有种危机感:要是这些软件下架了,我该怎么在iOS上(尤其是新设备)访问外网、使用TG呢?
解决办法之一是做一个自己的客户端,这样就永远不会下架。本人比较幸运,从闲下来找代码以及编译并测试使用正常,总共花了几个小时(主要时间是解决Cocospods的依赖安装)。上网查了一圈,貌似没有相关教程,于是有了此文。
本人从未用过Swift,无法对客户端功能进行修改,类似问题请勿咨询本人。如果可以,请购买
Potatso 2支持原作者,或者给haxpor等人捐赠。参考
- https://github.com/haxpor/Potatso
- https://www.jianshu.com/p/1711e131987d
- https://sspai.com/post/38909
- https://coolshell.cn/articles/1480.html
- https://cloud.tencent.com/developer/article/1072481
- https://mirror.tuna.tsinghua.edu.cn/help/CocoaPods/
from https://tlanyan.me/build-your-ios-vpn-client/
-------------------------------------------------------
构建Potatso问题集锦及解决方案
不少网友根据教程在构建时遇到各种问题。最初我以为是网友看教程不仔细或构建环境差异造成,没多注意。后来陆续有网友加我QQ,让我怀疑写完文章后代码有了重大更新。
终于在昨天(除夕)抽出时间,用最新版的代码构建Potatso并安装到我最新版iOS系统的iPad上。这个过程花费了几个小时,覆盖了许多网友咨询我的问题,本文中将一一给出解决方案。
如果你的Xcode版本是9.4.1,使用commitID为318a5e1的代码,根据“构建自己的iOS网络代理客户端”中的教程可以顺利的编译和安装Potatso到iOS12系统以下的设备。如果你的设备升级到了最新版,或者遇到其他问题,请继续阅读本文。
为什么执着于构建自用Shadowsocks客户端?由于iOS生态的封闭性,正常情况下只能通过App Store下载应用。应用下架后,会导致手机重置、购买买新设备后无法安装。安卓、Windows、MacOS则不会有这个问题,只要安装文件存在,总是有得用。所以针对iOS设备构建自用的客户端很有必要,尤其是SS这类随时有可能下架的应用。
如果构建过程中遇到本文列出以外的问题,欢迎留言或加Q群688196496。
构建步骤
这节简要回顾构建Potatso的流程:
1. 安装Cocospods
如果已安装,请略过此步。
- 更新系统的gem版本:打开终端,输入:
sudo gem update --system; - 设置国内gem源:
gem sources --list输出为https://gems.ruby-china.org/请略过此步;否则先删除官方源再添加gems国内源:gem sources --remove https://rubygems.org/; gem sources --add https://gems.ruby-china.org/; - 安装Cocospods:
sudo gem install cocoapods。
2. 构建Potatso
构建Potatso的步骤如下:
- 克隆代码:
git clone https://github.com/haxpor/Potatso.git; - 更新子模块:
cd Potatso; git submodule update --init; - 安装依赖:打开
Podfile,将第一行改成:source 'https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git'(使用清华的CocoaPods源),然后运行pod install --verbose; - 使用XCode打开
Potatso.xcworkspace; - 更改
Potatso及PacketTunnel、TodayWidget两个子项目的Bundle ID,例如本人分别改成:potatso.tlanyan.me、potatso.tlanyan.me.PacketTunnel和potatso.tlanyan.me.TodayWidget; - 更改
Potatso及PacketTunnel、TodayWidget两个子项目Capabilities中的App Group和Keychain Sharing的Group:在”App Groups”中删除原有的group.io.wasin.potatso,新增自己的group,例如:”group.potatso.tlanyan.me”;在”Keychain Sharing”中输入自己的group ID; - 打开”PotatsoBase/Potatso.m”文件,将
shareGroupIdentifier函数的返回值改成自己的group id; - 将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.
原因: pod依赖未安装
解决办法: 安装依赖,执行命令:
pod install --verbose2. 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/libyaml/yaml-0.1.4.tar.gz”
备注: 此解决方案来自貌似
LibYAML官方人员的回复,亲测可以。当然可以使用前文“构建自己的iOS网络代理客户端”中所说的网络劫持方法。3. Diff:/Podfile.lock: No such file or directory
使用新版代码并安装好依赖后,这应该是构建过程中最先出现的问题。
原因:根据错误描述跟踪脚本执行流程,发现是执行预构建脚本时
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
原因: 子模块的代码未下载
解决方案: 初始化子模块代码,执行命令: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…
原因: 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。
原因: team ID不在已添加的账号内
解决方案: 在属性页面的Team中选择自己的账号
7. Your account does not have sufficient permissions to modify containers. / No profiles for ‘xxxx’ were found
原因: 该Bundle ID已经被其他Apple ID使用
解决方案: 换一个新的.
8. An Application Group with Identifier ‘xxxx’ is not available. Please enter a different string.
原因: 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/Potatso/issues/117。注意pod安装依赖后,会更改Potatso.xcodeproj/project.pbxproj文件,直接编译会出现第二个问题。正确操作应当如下:先备份Potatso.xcodeproj/project.pbxproj文件,然后执行pod install --verbose,成功后将文件覆盖。后续出现pod依赖更新的情况也应该按此步骤操作。
10. Could not locate device support files
原因: Xcode版本过低,不支持iOS 12.1系统。根据官方页面,需要Xcode 10.
解决方案: 安装Xcode 10,文件较大,根据网速需要一定时间,请耐心等待
11. Invalid redeclaration of ‘<- enumoprators.swift="" h3="">->
原因: ObjectMapper的版本过低
解决办法: 使用新版的ObjectMapper:打开Podfile,将ObjectMapper那一行改成pod 'AlamofireObjectMapper', '~> 5.0'
备注: 解决方案参考https://stackoverflow.com/questions/53038918/xcode-10-update-issue-with-alamofire-objectmapper
12. Type ‘RLMIterator‘ does not conform to protocol ‘Sequence’
原因: 这个问题不清楚具体原因。怀疑是Realm这个库的问题,没有实现Sequence接口。我将RealmSwift改到最新的3.7.6问题亦没有解决。不懂Swift,不过感觉是RMLIterator或者Proxy/RuleSet等存在问题。
解决办法: 注销PotatsoMode/DBUtils.swift中的相关代码,具体是174-190和202-218行之间的代码。
备注: 解决方案来自:https://github.com/haxpor/Potatso/issues/109。所有错误中,只有这个错误不是完美解决。
13. Initializer for conditional binding must have Optional type, not ‘[Rule]’
原因: 非nil值不应该使用if let(我自己的理解,毕竟不懂Swift)
解决办法: 将Potatso/Core/API.swift第65和256行的if和大括号去掉,65行修改示意:
// 修改前
// if let parsedObject = Mapper().mapArray(JSONArray: rulesJSON as! [[String : Any]]){
// let parsedObject = Mapper().mapArray(JSONArray: rulesJSON as! [[String : Any]])
// rules.append(contentsOf: parsedObject)
//}
// 修改后
let parsedObject = Mapper().mapArray(JSONArray: rulesJSON as! [[String : Any]])
rules.append(contentsOf: parsedObject)
备注: 解决办法的灵感来自:https://stackoverflow.com/questions/31038759/conditional-binding-if-let-error-initializer-for-conditional-binding-must-hav。当然这个问题和Potatso无关。
from https://tlanyan.me/build-potatso-problems-and-solutions/
No comments:
Post a Comment