美文网首页57e60d08dc49iOS DeveloperiOS技术资料
iOS开发实战-NetworkExtension食用教程

iOS开发实战-NetworkExtension食用教程

作者: gwk_iOS | 来源:发表于2017-07-12 21:45 被阅读942次

    写在前面

    之前由于一些关键字问题被简大叔给封锁了...我还是换成正常的来吧~鉴于此顺便给自己开了个 简单的wordpress博客有兴趣的可以去看看吧~~~
    最近闲来无事,又跟小伙伴搞起.自由冲浪.的项目,于是这个项目就来了.

    项目介绍

    运用Apple NetworkExtension框架(现在不用单独申请了哟),搭配NEKit 配置S最终实现....上网

    • 首先感谢zhuhaow的优秀框架NEKit帮我们做了很多网络相关的处理,原则上我们只用专注UI就可以很方便的在iOS OSX平台开发出一个简单的S客户端

    • 再来就是感谢称一称小哥的优秀Demo,该Demo几乎就是一个iOS平台的S客户端

    • 本项目为Swift项目

    • 根据NEKit的使用帮助,这边第三方类库管理工具我们使用Carthage

    • 本文已称一称小哥的Demo为主

    项目准备

    一.安装NEProviderTargetTemplates.pkg

    由于未知原因苹果在mac OS 10.12中删除了这个文件,因此我们需要从10.11系统中提取或下载--百度网盘
    安装完毕后,在新增build target中我们就可以看到多了AppProxy和 Package Tunnrl Provider。我们选择Package Tunnrl Provider

    选择target Package Tunnrl Provider

    打开项目将2个Target的Capabilites中的PersonalVPN和NetworkExtesions开关打开,注意是两个都开哦

    打开PersonalVPN和NetworkExtesions

    二.连接VPN

    首先,我们需要在主程序中像系统生名一个ProviderManager,即设置VPN中的栏目。

    let manager = NETunnelProviderManager()
    let conf = NETunnelProviderProtocol()
    conf.serverAddress = "My VPN"          //任意值,显示在设置-VPN-Detial中
    manager.protocolConfiguration = conf
    manager.localizedDescription = "My VPN"
    manager.isEnabled = true               //使VPN在系统中变为选中的状态
    
    NETunnelProviderManager.loadAllFromPreferencesWithCompletionHandler{ 
        (managers, error) in
        guard let managers = managers else{return}
        let manager: NETunnelProviderManager
        if managers.count > 0 {
            manager = managers[0]
        }else{
            manager = self.createProviderManager()
        }
        // Todo
        // manager.saveToPreferences.......
    }
    

    三.简单配置extension

    由于目前我使用的是Swift3.0,这时候我们需要修改Extension中的几个方法修改一下

    //MARK: 启动VPN时调用
    func startTunnel(options: [String : NSObject]? = nil, completionHandler: @escaping (Error?) -> Swift.Void)
    
    //MARK: 停止VPN时调用
    func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Swift.Void) 
    

    四.启动VPN

    启动VPN很简单,只需对ProviderManager执行startVPNTunnelWithOptions()方法即可

    saveToPreferences{
       error in
       //出错处理
       manager.loadFromPreferences{
            if $0 != nil{print($0)}
            manager.startVPN.........
        }
    }
    

    连接成功会manager.connection.status会发生相应改变,因此我们需要在按下连接按钮后监听status,从而知道目前Vpn的连接状态

     func addVPNStatusObserver() {
         guard !observerAdded else{
             return
         }
         loadProviderManager { [unowned self] (manager) -> Void in
             if let manager = manager {
                 self.observerAdded = true
                 NotificationCenter.default.addObserver(forName: NSNotification.Name.NEVPNStatusDidChange, object: manager.connection, queue: OperationQueue.main, using: { [unowned self] (notification) in
                     self.updateVPNStatus(manager: manager)
                 })
             }
         }
     }
    

    五.关于Debug调试

    • Extension debug不同于正常的程序,尽量使用NSlog代替print,即可在系统日志中查看到内容。同时,如果需要Debug,可通过Xcode->Debug->Attach To Process 选择你的Tunnel名进行debug
      打开控制台console就能看到所有日志 筛选一下当前的target就能看到日志信息了

    六.传SS递配置文件

    我们需要在主程序中传递类似账号、密码、端口、加密方式等参数给我们的VPN组件。

    • 主程序写入
    let conf = ["port":1000,"method":"AES-256-CFB","password":"hello"]
    let providerProtocol = manager.protocolConfiguration as! NETunnelProviderProtocol
    providerProtocol.providerConfiguration = conf
    manager.protocolConfiguration = orignConf
    
    • target读取
    public var protocolConfiguration: NEVPNProtocol { get }
    
    guard let conf = (protocolConfiguration as! NETunnelProviderProtocol).providerConfiguration else{
        NSLog("[ERROR] No ProtocolConfiguration Found")
        exit(EXIT_FAILURE)
    }
    let address = conf["address"] as! String
    let port = conf["port"] as! Int
    
    

    七.导入NEKit

    根据NEKit导入方法 直接导入即可
    导入成功后记得copy framework哦,脚本copy和手动添加都是可行的

    八.上架问题

    90080,90087,90209,90125报错

    在上架时如果直接使用会报错90080,90087,90209,90125等错误,这是由于NEKit中包含了x86_64, i386 架构,当然这个AppStore是不允许的,所以会在上传的时候报错
    解决方法: Build Phases - New Run Script Phase


    Build Phases - New Run Script Phase

    添加如下代码

    APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
    
    # This script loops through the frameworks embedded in the application and
    
    # removes unused architectures.
    
    find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK
    
    do
    
    FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
    
    FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
    
    echo "Executable is $FRAMEWORK_EXECUTABLE_PATH"
    
    EXTRACTED_ARCHS=()
    
    for ARCH in $ARCHS
    
    do
    
    echo "Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME"
    
    lipo -extract "$ARCH" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$ARCH"
    
    EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$ARCH")
    
    done
    
    echo "Merging extracted architectures: ${ARCHS}"
    
    lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[@]}"
    
    rm "${EXTRACTED_ARCHS[@]}"
    
    echo "Replacing original executable with thinned version"
    
    rm "$FRAMEWORK_EXECUTABLE_PATH"
    
    mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH"
    
    done
    
    添加代码

    CFBundleShortVersionString报错

    这是由于NEKit没有设置版本号
    找到NEKit的framework将info.plist中的版本号


    找到info.plist 修改版本号

    九.Demo食用方法

    • 添加CommonCryptoframework

    由于CommonCrypto框架的问题需要在Cartfile中添加
    github "soffes/CommonCrypto"

    • 导入NEKit

    按照demo上使用Carthage导入NEKit
    运行carthage update --no-use-binaries --platform ios
    关闭项目Capabilites中AppGroups开关 将entitlements中相关的 groups属性删除即可

    我不是广告

    宣传一波牛.牛牛.牛牛.牛8折优惠码:MHO5TKGQ64 (只能用10次哦~) 已锐速,欢迎免费体验,希望你们看到的时候还没被请去喝茶

    结语

    最后再次感谢NEKit👍和称一称提供的Demo 👍

    很高兴App 已经过审, 有兴趣的可以玩玩牛牛数据 支持iPad哦
    update:
    Mac版已成功上架
    牛牛数据Mac版~~

    相关文章

      网友评论

      • Har_vey:Hub connection error Error Domain=NSCocoaErrorDomain Code=4097
        这是报的错误 遇到过没有呢
        gwk_iOS:@Har_vey 你可以看下issue,https://github.com/zhuhaow/NEKit/issues/80
      • Har_vey:哥们儿 能不能问下你一个问题,
        现在rabbitVpn已经成功链接了VPN,
        因为我们项目使用的是OC,现在把swift netkit框架导入了工程,新建了PacktTunnel 里面的PacketTunnelProvider文件是swift rabbitVPN的源文件,但是我现在没法链接,请问下是哪里出错了呢
      • Farmers:兄弟 有源码么?

      本文标题:iOS开发实战-NetworkExtension食用教程

      本文链接:https://www.haomeiwen.com/subject/zrlihxtx.html