使用发布版本有效地测试iPhone应用程序

时间:2010-10-04 13:46:28

标签: iphone objective-c crash linker

我们的应用程序已在App Store上发布的armv6 iOS设备上崩溃。 armv7 iOS设备运行得很好。当应用程序构建并作为调试进行测试时,它在armv6armv7上都运行良好。在日志中,我试图从库中构造对象时得到EXC_BAD_INSTRUCTION。崩溃似乎是发布版本的链接错误,因为我有三个来自three20的静态库。起初我认为这是一个iOS版本问题,但它现在看起来像一个“胖二进制”问题。

ad-hoc是使用模拟App Store进行测试的最佳方式吗?在设备上测试发布版本的最佳方法是什么?在发布构建中测试与不同设备的链接的最佳方法是什么?

4 个答案:

答案 0 :(得分:1)

我找不到iOS兼容性测试实验室的参考,但我听说目前可用。如果我能找到这个资源,我会更新我的回复。

同时,您可以在此处找到UI自动化测试建议:Automated testing for iPhone

不幸的是,你必须找到一款3g iPhone来验证arm6的兼容性。我希望你能够通过询问每个知道谁有新iPhone的人来找到一个容易的。他们可能像我一样将旧手机放在抽屉里。我用我的测试。

如果你可以证明一个复杂的解决方案,你可以永久地将旧的iPhone连接到mac mini并使用上面引用的UI测试框架使用Hudson或CruiseControl来驱动UI。如果您可以进行前期投资,这将是最可靠和最耗时的方法。

答案 1 :(得分:1)

您可以使用 codesign 命令行工具更改内置应用程序的代码签名权限。构建分发目标后,应用程序文件将具有“分发”权限;您需要将其更改为开发权限。在更改之后,您可以在开发设备上安装构建并进行测试。

要查看应用程序签名的详细转储:

$ codesign -d -vv MyApp.app/MyApp

更改代码签名权限:

$ codesign -f -s "My iPhone Developer Name" -vv MyApp.app/MyApp

您可能需要创建一个环境变量来获取codeign_allocate的正确版本:

$ export CODESIGN_ALLOCATE=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate

我在Craig Hockenberry的博客上找到了这些指示,其中包含有关此流程的大量其他信息:http://furbo.org/2008/11/12/the-final-test/

答案 2 :(得分:1)

我能够使用ad-hoc分发来测试它。

答案 3 :(得分:-1)

我使用ANT创建版本,使用xcodebuild命令行实用程序。蚂蚁目标看起来像这样:

 <target name="build-adhoc">
        <echo>Running XCODE compiler</echo>
        <exec executable="xcodebuild" failonerror="true" vmlauncher="false" dir="${connect_src}">
            <arg value="build"/>
            <arg value="-target" />
            <arg value="myappname" />
            <arg value="-configuration"/>
            <arg value="AdHoc"/>
            <arg value="SYMROOT=${export_app}-${version.number}/AdHoc" />
            <env key="USER_HEADER_SEARCH_PATHS" value="/tmp/build/trunk/Libraries/somesource/**\ /tmp/build/trunk/Libraries/somemoresource/**"/>
        </exec>
        <echo>xcode build complete</echo>
    </target>

为您的临时版本创建配置,并确保它使用临时就绪配置文件。或者,您可以创建使用开发人员配置文件的常规非临时配置。如果您执行前者,则可以将产品以及配置文件通过电子邮件发送给测试人员。如果您执行后者,则可以使用iPhone Config Utility在配置文件中的任何设备上进行安装。

此外,我们有ANT目标设置,依赖于从源代码控制执行新的签出并从那里执行构建。最后,我们使用真正的App Store就绪配置进行构建,这样我们就可以测试第一个构建并将第二个构建到Apple,并确保代码行为是相同的。

以下是处理顺序的ANT目标摘要:

  1. 设置构建所需的env vars
  2. 清除结帐并构建目录
  3. 从源代码管理中检出HEAD
  4. 修改plists以删除仅供内部使用的调试和元素(使用PLISTBUDDY)
  5. 增加构建版本(使用agvtool)
  6. 运行单元测试(这需要将sdk设置设置为iphonesimulator4.x和一个特殊目标 - 请参阅iPhone开发人员指南进行单元测试)
  7. 进行内部构建(使用dev配置文件或ad hoc配置文件)
  8. 进行分发构建(使用App Store分发证书)
  9. 签入具有新版本
  10. 的plist文件
  11. 在源代码管理中执行指示构建的标记
  12. 报告构建统计信息(构建版本,位置等)
  13. 注意:确保在xcodebuild命令语法中设置SYMROOT env变量,以便您的构建最终位于正确的目录中。我们在事后复制App Store构建时遇到了问题。

    以下是用于创建多个构建的完整ANT脚本,一个用于测试,一个用于分发。例如:“ant distribution”将使用dev配置文件创建一个版本,使用App Store分发配置文件创建一个版本。

    此脚本已“清理”,因此它仅作为开始使用的模型:

    <?xml version="1.0" ?>
    
    <project basedir="." default="xcode-build" name="Temp">
        <property file="build.properties" />
        <property name = "CONFIGURATION_INTERNAL" value = "InternalRelease" />
        <property name = "CONFIGURATION_DISTRIBUTION" value = "Distribution" />
        <property name = "CONFIGURATION_ADHOC" value = "InternalAdHoc" />
        <property name="cvsroot" value=":pserver:${username}:${password}@${cvsurl}"/>
        <tstamp>
          <format property="TODAY"
                  pattern="MM-dd-yyyy"
                  locale="en,US"/>
        </tstamp>
    
    
        <target name="init">
            <echo message="deleting old directories" />
            <delete dir="${check_out_location}"/>
            <mkdir dir="${check_out_location}"/>
        </target>
    
    
        <target name="set-source-trees" depends="init">
        <echo message="exporting source tree variables" />
            <echo message="${somesourcedir}" />
            <exec executable="/bin/bash" os=" Mac OS X">
                <arg value="-c" />
                <arg value="${export_src_trees}"/>
                <arg value="${anothersourcedir}"/>
            </exec>
            <exec executable="/bin/bash" os=" Mac OS X">
                <arg value="-c" />
                <arg value="${export_src_trees}"/>
                <arg value="${yetanothersourcedir}"/>
            </exec>
        </target>
    
    
        <target name="cvs-login" depends="init" description="CVS Login">
            <echo>Login CVS</echo>
            <cvs cvsroot=":pserver:${username}:${password}@${cvsurl}" command="login" />
        </target>
    
        <target name="checkout" depends="cvs-login" description="Check out source from CVS">
            <echo message="check out from CVS ...." />
            <echo message="${check_out_location}" />
            <cvs cvsroot="${cvsroot}"  command=" -Q checkout -P -d${project_trunk} ${project_repository_root}/${project_trunk} " dest="${check_out_location}" compression="true" />
            <echo message="...check out from CVS done" />
        </target>
    
    
         <target name="strip-settings" depends="checkout" description="Remove elements from the Settings.bundle that we don't want in the distribution">
            <echo message="Removing Settings not valid for distribution"/>
    
            <exec executable="/usr/libexec/PlistBuddy" failonerror="TRUE" dir="${app_src}/Resources">
                <arg value="-c"/>
                <arg value="Delete :PreferenceSpecifiers:3"/>
                <arg value="Settings.bundle/Root.plist"/>
            </exec>
    
            <exec executable="/usr/libexec/PlistBuddy" failonerror="TRUE" dir="${app_src}/Resources">
                <arg value="-c"/>
                <arg value="Delete :PreferenceSpecifiers:3"/>
                <arg value="Settings.bundle/Root.plist"/>
            </exec>
        </target>
    
    
        <target name="build-version" depends="checkout">
    
            <property name = "LOGLEVEL" value = "DEBUG" />
    
           <!-- GET THE NEXT VERSION NUMBER (major and minor) -->
            <exec executable="/tmp/build/trunk/Build/version.sh" failonerror="TRUE" outputproperty="version.number" dir="${app_src}"></exec>
    
            <echo message="Increment Build Number"/>
    
            <exec executable="agvtool" failonerror="TRUE" dir="${app_src}">
                <arg value="new-version"/>
                <arg value="-all"/>
                <arg value="${version.number}"/>
            </exec>
    
            <!-- GET THE MINOR portion of the version number for later use -->
            <exec executable="/tmp/build/trunk/Build/minor.sh" failonerror="TRUE" outputproperty="version.minor" dir="${app_src}"></exec>
    
            <!-- SET the version number as reference in the Settings.bundle -->
            <exec executable="/usr/libexec/PlistBuddy" failonerror="TRUE" dir="${app_src}">
                <arg value="-c"/>
                <arg value="Set :PreferenceSpecifiers:1:DefaultValue ${version.number}"/>
                <arg value="./Resources/Settings.bundle/Root.plist"/>
            </exec>
    
            <echo message="New build number=${version.number}"/>
    
            <!-- SET the log level - NOTE, ANT vars are immutable, if LOGLEVEL was previously set, it cannot be overridden -->
            <exec executable="/usr/libexec/PlistBuddy" failonerror="TRUE" dir="${app_src}">
                <arg value="-c"/>
                <arg value="Set LogLevel.Default ${LOGLEVEL}"/>
                <arg value="./Resources/SharedConfig.plist"/>
            </exec>
            <echo message="Log level set to ${LOGLEVEL}"/>
    
        </target>
    
    
         <target name="encrypt" depends="build-version">
            <!-- SOME ENCRYPTION OF SENSITIVE DATA -->
        </target>
    
    
        <target name="build-internal" depends="test-lib1, test-lib2, test-app, encrypt">
            <echo>Running XCODE compiler</echo>
            <exec executable="${xcode_builder}" failonerror="true" vmlauncher="false" dir="${app_src}">
                <arg value="clean"/>
                <arg value="install"/>    
                <arg value="-target" />
                <arg value="MyApp" />
                <arg value="-configuration"/>
                <arg value="${CONFIGURATION_INTERNAL}"/>
                <arg value="SYMROOT=${build_release}" />
                <env key="USER_HEADER_SEARCH_PATHS" value="/tmp/build/trunk/Libraries/somesource/**\ /tmp/build/trunk/Libraries/someothersource/**"/>
            </exec>
            <echo>xcode build complete</echo>
        </target>
    
         <target name="test-lib1" depends="checkout">
            <echo>Running XCODE compiler</echo>
            <exec executable="${xcode_builder}" failonerror="true" vmlauncher="false" dir="${somelib_dir}">
                <arg value="clean"/>
                <arg value="build"/>
                <arg value="-target" />
                <arg value="Lib1UnitTests"/>
                <arg value="-sdk"/>
                <arg value="iphonesimulator4.1"/>
                <arg value="SYMROOT=${build_release}" />
            </exec>
            <echo>xcode build complete</echo>
        </target>
    
         <target name="test-lib2" depends="checkout">
            <echo>Running XCODE compiler</echo>
            <exec executable="${xcode_builder}" failonerror="true" vmlauncher="false" dir="${somelib2_src_dir}">
                <arg value="clean"/>
                <arg value="build"/>
                <arg value="-target" />
                <arg value="Lib2UnitTests"/>
                <arg value="-sdk"/>
                <arg value="iphonesimulator4.1"/>
                <arg value="SYMROOT=${build_release}" />
                <env key="USER_HEADER_SEARCH_PATHS" value="/tmp/build/trunk/Libraries/Lib1source/**"/>
            </exec>
            <echo>xcode build complete</echo>
        </target>
    
          <target name="test-app" depends="checkout">
            <echo>Running XCODE compiler</echo>
            <exec executable="${xcode_builder}" failonerror="true" vmlauncher="false" dir="${app_src}">
                <arg value="clean"/>
                <arg value="build"/>
                <arg value="-target" />
                <arg value="AppUnitTests"/>
                <arg value="-sdk"/>
                <arg value="iphonesimulator4.1"/>
                <arg value="SYMROOT=${build_release}" />
                <env key="USER_HEADER_SEARCH_PATHS" value="/tmp/build/trunk/Libraries/Lib1/**\ /tmp/build/trunk/Libraries/Lib2/**"/>
            </exec>
            <echo>xcode build complete</echo>
        </target>
    
         <target name="build-distribution" depends="internal-release, test-lib1, test-lib2, test-app">
            <echo>Running XCODE compiler</echo>
            <exec executable="${xcode_builder}" failonerror="true" vmlauncher="false" dir="${app_src}">
                <arg value="build"/>
                <arg value="-target" />
                <arg value="MyApp" />
                <arg value="-configuration"/>
                <arg value="${CONFIGURATION_DISTRIBUTION}"/>
                <arg value="SYMROOT=${export_app}-${version.number}/Distribution" />
                <env key="USER_HEADER_SEARCH_PATHS" value="/tmp/build/trunk/Libraries/Lib1/**\ /tmp/build/trunk/Libraries/Lib2/**"/>
            </exec>
            <echo>xcode build complete</echo>
        </target>
    
        <target name="build-adhoc" depends="internal-release, test-lib1, test-lib2, test-app">
            <echo>Running XCODE compiler</echo>
            <exec executable="${xcode_builder}" failonerror="true" vmlauncher="false" dir="${app_src}">
                <arg value="build"/>
                <arg value="-target" />
                <arg value="MyApp" />
                <arg value="-configuration"/>
                <arg value="${CONFIGURATION_ADHOC}"/>
                <arg value="SYMROOT=${export_app}-${version.number}/AdHoc" />
                <env key="USER_HEADER_SEARCH_PATHS" value="/tmp/build/trunk/Libraries/Lib1/**\ /tmp/build/trunk/Libraries/Lib2/**"/>
            </exec>
            <echo>xcode build complete</echo>
        </target>
    
    
        <target name="checkin" depends="build-internal" description="Commit source to CVS" >
            <echo message="Committing to CVS ...." />
            <echo message="${check_out_location}" />
    
             <cvs cvsroot="${cvsroot}"  command="commit -m 'Commit of internal release build ${version.number}' MyApp-Info.plist" dest="${check_out_location}/trunk/Applications/MyApp" />
            <echo message="...commit done" />
        </target>
    
    
         <target name="tag-release" depends="checkin" description="Tag source in CVS" >
            <echo message="Tagging source ... Release-${version.minor}" />
            <echo message="${check_out_location}" />
            <cvs cvsroot="${cvsroot}"  command="tag Release-${version.minor}" dest="${check_out_location}"/>
            <echo message="...tag done" />
        </target>
    
    
         <target name="internal-release" depends="tag-release" description="Tag source in CVS" >
            <echo message="Creating Internal release ..." />
            <echo message="Deploying files to . . .${export_app}" />
            <copy todir="${export_app}-${version.number}">
                <fileset dir="${prod_dir_internal}"/>
            </copy>
    
            <echo message="Internal release ${version.number} complete." />
        </target>
    
    
         <target name="override-default-env"  description="Setup Env for Distribution" >
                    <property name = "LOGLEVEL" value = "WARN" />
         </target>
    
    
         <target name="distribution" depends="override-default-env, strip-settings, build-distribution" description="Create Distribution" >
    
            <echo message="Creating Distribution ..." />
            <echo message="Deploying files to . . .${export_app}-${version.number}/Distribution" />
            <echo message="Distribution ${version.number} complete." />
    
        </target>
    
         <target name="adhoc" depends="override-default-env, strip-settings, build-adhoc" description="Create Ad Hoc Distribution" >
    
            <echo message="Creating ad hoc distribution ..." />
            <echo message="Deploying files to . . .${export_app}-${version.number}/AdHoc" />
            <echo message="Ad hoc distribution ${version.number} complete." />
    
        </target>
    
    
    </project>
    
    Hope this helps.