美文网首页iOS
iOS开发:集成的SDK不支持模拟器调试怎么办?

iOS开发:集成的SDK不支持模拟器调试怎么办?

作者: tigerMonkey | 来源:发表于2019-09-28 21:50 被阅读0次

      最近在项目的开发中遇到了一个问题。用户反映在iPhone Xs Max上一些界面显示异常。但是手头没有这个手机,而且自从集成了萤石云的SDK以后,项目无法在模拟器上调试。现在再申请购置一部XS Max手机也来不及了,而且总不能一遇到手头没有的设备就申请新手机吧。于是就需要考虑如何让这种集成了不支持模拟器的SDK如何也能在模拟器上运行,从而解决这类项目中遇到的个别机型差异造成的BUG。

    一、什么情况下出现这种问题

      刚才说了,出现在这种问题是集成了第三方的SDK,该SDK不支持模拟器运行。其实,再问题具体一点,是因为这类SDK不支持在x86下编译的话,则不能在模拟器上调试运行。

    二、解决这种问题的思路。

      其实,解决这类问题的方法就是四个字:条件编译。利用条件编译,在模拟器环境下不对不支持x86的SDK进行编译即可。

      对于有些SDK提供了两套版本,一套Release环境,一套Debug环境。Debug环境支持在模拟器进行,对于这类SDK,则可以通过替换SDK的framework的方式来解决模拟器调试问题。比如阿里云短视频SDK,七牛视频播放SDK等等。

    三、具体解决问题的方法。

      我们要设置一个预编译宏,来处理条件编译,比如设置一个预编译宏,名字叫EZDISABLE。在TargetBuild Settings选项卡下面,我们找到Preprocessor Macros项,双击后增加一项:EZDISABLE=1。可以只在Debug或者只在Release加入该宏,具体依据你自己的需求而定。这里我都加入了。

      下面,就是将用到不支持x86的SDK的调用,通过EZDISABLE“隔离”开。在我这个项目中,需要把萤石云的SDK“隔离”

    // 如果没有定义EZDISABLE宏, 则编译以下内容, 否则不编译
    #ifndef EZDISABLE
    #import <EZOpenSDKFramework/EZOpenSDKFramework.h>
    #endif
    ......
    ......
    
    - (void)setupEZ{
    // 如果没有定义EZDISABLE宏, 则编译以下内容, 否则不编译
    #ifndef EZDISABLE
       [EZOpenSDK initLibWithAppKey:@"xxxxxx"];
    #endif
    }
    

      代码可能分散的比较多,需要耐心的一个个把他给去掉。

      上面还说了,有些SDK分ReleaseDebug两个版本,Debug支持模拟器编译。对于这类,如果你的SDK是通过手工添加的方式来集成的话,那你就手工一个个一个把SDK给替换了,如果你用的是cocoaPods的话,那一般只需要将Podfile的引用稍作修改既可以。我这个用的是cocoaPods来集成的七牛视频播放SDK。我将Podfile文件修改成下面的即可:

    source 'https://github.com/CocoaPods/Specs.git'
    platform :ios, '8.0'
    inhibit_all_warnings!
    target 'BBTSer' do
      ...
      ...
      pod "PLPlayerKit", :podspec => 'https://raw.githubusercontent.com/pili-engineering/PLPlayerKit/master/PLPlayerKit-Universal.podspec'  #七牛官方提供的支持模拟器的版本,在官方网站上可以查到
    end
    

      有时候,我们为了方便代码的复用,做了很多的私有Pod子库提供给主项目集成。如果在这些私有库中引用了类似七牛这种SDK该怎么办?其实我们根据cocoaPods的规则,完全可以不用考虑子库,直接在主工程的Podfile文件将SDK的引用改了就行。cocoaPods会自动处理这类依赖,非常方便。

    四、问题优化。

      在上面,已经基本上解决了如何在模拟器上编译的问题。但是不太方便,我们总不能每次切换真机与模拟器的时候,都去修改一下预编译宏和Podfile文件吧?

      具体该怎么进行优化可以让我们方便的切换调试环境呢?

      对于预编译宏的设置,我们可以通过再设置一个Target的方式来处理,我们将工程的Target复制一个,比如原工程Target名字为:BBTSer。复制的一个改名为:BBTSer Simulator。我们只在BBTSer SimulatorBuild Settings选项卡中的Preprocessor Macros增加预编译宏EZDISABLE=1。原来的老Target不变。如果用cocoaPods的话,在增加了一个新的Target后要相应的修改一下Podfile文件来增加对这个Target的支持。这样,就可以通过切换Target的方式来处理真机与模拟器的调试切换。

      再说下Podfile文件的优化。上面讲了,对于七牛的SDK官方支持了在模拟器调试,但是是不同的pod库地址。需要进行切换。那么我们如何能够使cocoaPod能够以一种相对自动的方式来处理这种切换呢?这需要我们更加的了解Podfile的语法才行。首先,在上面我们建立了两个Target。所以Podfile文件要同时处理两个Target的集成。然后,对于不同的Target有可能要集成不同的七牛SDK地址,如何在pod install的时候来处理这种不同?

      对于第一个问题其实很简单,百度一下很多方式,这里不在叙述。对于第二个问题需要说一下。在Podfile中,如果两个或者多个Target引用了相同的pod库,但是源文件地址不一样的话,是会报错的。那么我们就需要增加一个开关来处理一下,如果开关打开,则引入正常地址,如果开关关闭则引入另外一个地址。我们知道,Podfile文件的语法其实跟Ruby差不多。所以,我们可以增加一个变量release,然后通过判断release变量是false还是true来引入不同的源地址。这样,我们的Podfile文件就变成了如下行使。

    source 'https://github.com/CocoaPods/Specs.git'
    platform :ios, '8.0'
    inhibit_all_warnings!
    #开关变量
    release=false
    # abstract_target:抽象target。内部包含两个Target:BBTSer和BBTSer Simulator。这两个Targe继承这个抽象target。抽象target的名字可以随意定义,这里我定义成BBT
    abstract_target 'BBT' do    
      ...
      ...
      if release then
        target 'BBTSer' do
          pod "PLPlayerKit"
        end
      else
        target 'BBTSer Simulator' do
          pod "PLPlayerKit", :podspec => 'https://raw.githubusercontent.com/pili-engineering/PLPlayerKit/master/PLPlayerKit-Universal.podspec'
        end
      end
    end
    

    到了这里,我们在每次切换模拟器和真机的时候,只要把release的状态改一下就可以了,真机改成true,模拟器改成false。然后在pod install或者pod update。你可能会说,这样也不好。每次还要改Podfile文件。那么好,我再加一个shell脚本,来帮着我们处理这个改动,不要每次都改Podfile文件了,省的不小心改错了。shell文件起名为podinstall.sh。内容如下:

    #!/bin/bash
    file="Podfile"
    if [ ! -f "$file" ]; then
      echo '没有找到Podfile文件'
      exit
    fi
    
    if [ ! -n "$1" ] ;then
        echo "请输入参数。真机调试以及发布到AppStore请输入release,模拟器调试输入debug"
        exit
    fi
    
    MODE=$1
    if [ "$MODE" != "release" ] && [ "$MODE" != "debug" ];then
        echo "请输入正确的参数。真机调试以及发布到AppStore请输入release,模拟器调试输入debug"
        exit
    fi
    echo "当前集成环境:$MODE"
    
    podmodel="release=false"
    if [ "$MODE" == "release" ];then
        podmodel="release=true"
    fi
    echo $podmodel
    # sed -i "s/release=true/$podmodel/g" 
    # sed -i '' '/release=true/$podmodel/g' $file
    sed -i '' "s#release=true#$podmodel#g" $file
    sed -i '' "s#release=false#$podmodel#g" $file
    
    #更新pod配置
    echo "********************************************"
    echo "*      配置完毕,开始Pod集成        *"
    echo "********************************************"
    pod install
    

    每次pod install的时候,用这个shell来代替。将它和Podfile文件放到一起。真机pod调用./podinstall.sh release。模拟器pod调用./podinstall.sh debug。怎么样,是不是方便多了?

    相关文章

      网友评论

        本文标题:iOS开发:集成的SDK不支持模拟器调试怎么办?

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