Effectively test iPhone apps with releases

We have an application crashed on armv6 iOS devices that come from the App Store. armv7 iOS devices did a great job of this. When the application was built and tested as debugging, it worked perfectly on both armv6 and armv7 . In the logs, I got EXC_BAD_INSTRUCTION when I tried to create an object from the library. The error was due to a release assembly binding error, since I have several static libraries out of three20. At first I thought it was a problem with the iOS version, but now it looks like a "bold binary" problem.

Is ad-hoc the best way to have a simulated app store for testing? What is the best way to test release builds on a device? What would be the best way to test connectivity with various devices in a release build?

+4
source share
4 answers

I was able to test it using ad-hoc distribution.

+1
source

I cannot find a link to the iOS compatibility testing lab, but I heard that it is currently available. If I can find this resource, I will update the answer.

At the same time, you can find advice on testing user interface automation : Automated testing for iPhone

Unfortunately, you will need to find a 3g iPhone to check for compatibility with arm6. I expect that you can find it quite easily by simply asking everyone you know who has the new iPhone. They probably have an old phone sitting in a drawer, like me. I use mine for testing.

If you can justify a complicated solution, you can permanently connect your old iPhone to the mini-mini and control the user interface using the above user interface testing framework using Hudson or CruiseControl. This would be the most reliable and least time consuming approach if you can do it through investment.

+1
source

You can change the code signing authority in the embedded application using the codeign command-line tool . After creating your distribution target, the application file will have the โ€œdistributionโ€ authority; you need to change it to development authority. After the change, you can install the assembly on the development device and test it.

To see a detailed application signature dump:

 $ codesign -d -vv MyApp.app/MyApp 

To change permissions for codes:

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

You may need to create an environment variable to get the correct version of codesign_allocate:

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

I found these directions on the Craig Hockenberry blog with lots of additional information about this process: http://furbo.org/2008/11/12/the-final-test/

+1
source

I use ANT to create releases using the xcodebuild command-line utility. The purpose of ANT is as follows:

  <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> 

Create an ad hoc release configuration and make sure that it uses the off-the-shelf provisioning profile. Or you can create a regular, non-ad hoc configuration that uses a developer training profile. If you do the first, you can email the product along with a tester training profile. If you do the latter, you can use the iPhone Config utility to install on any device in your profile.

In addition, we have a targeted ANT installation with dependencies on performing a new check on the original control and building the assembly from there. Finally, we build right after that, using the actual configuration of the App Store, so that we can test the first build and send the second to Apple, with some certainty that the behavior of the code will be the same.

Here is a summary of our ANT goals in processing order:

  • install env vars necessary for assembly
  • clear and create directories
  • checkout HEAD from control source
  • modify plists to remove debugging and elements for internal use only (using PLISTBUDDY)
  • Build version increment (using agvtool)
  • Run unit tests (this requires installing sdk on iphonesimulator4.x and a special purpose - see the iPhone Developers Guide for unit testing).
  • Internal assembly (using dev or ad hoc profile)
  • Create a distribution (using the App Store distribution certificate)
  • Plin files with a new build version
  • Make a tag in the source control pointing to the assembly
  • Reporting statistics (build version, location, etc.).

NOTE. Make sure you set the env SYMROOT variable in the syntax of the xcodebuild command so that your assembly is in the appropriate directory. We had problems copying the App Store assembly after the fact.

Here is the complete ANT script used to create multiple assemblies, one for testing and one for distribution. For example: "ant distribution" will create one assembly using the dev profile, and one using the App Store distribution profile.

This script is "cleared", so it serves only to start:

 <?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. 
-1
source

All Articles