Xcode: Difference between revisions

From iPhone Development Wiki
(removing extra space)
mNo edit summary
(6 intermediate revisions by 5 users not shown)
Line 1: Line 1:
'''Xcode''' is ''the'' IDE endorsed by Apple for iOS development. The latest stable version is 5.0. It comes with the official iOS SDK.  
'''Xcode''' is ''the'' IDE endorsed by Apple for iOS development. The latest stable version is 6.0.1. It comes with the official iOS SDK.  


For notes about using Logos and Theos with Xcode, see [[Xcode Logos]].
For notes about using Logos and Theos with Xcode, see [[Xcode Logos]].


== Developing without Provisioning Profile ==
== Developing application without iOS Developer program membership (aka without Provisioning Profile) ==
 
To develop for the device, one should first obtain a provisioning profile by joining the iPhone Developer Program (which costs $99). However, some simple tricks can be used to make Xcode compile and debug on jailbroken devices without provisioning profiles.
To develop for the device, one should first obtain a provisioning profile by joining the iPhone Developer Program (which costs $99). However, some simple tricks can be used to make Xcode compile and debug on jailbroken devices without provisioning profiles.


'''The following instructions (under "Old instructions") are outdated.''' See [http://www.sysrage.net/guides/ios-programming/building-and-running-ios-applications-without-a-paid-developer-license Building and Running iOS Applications Without A Paid Developer License] for a newer guide. ''However, that guide is incomplete.'' Make sure to set <code>ENTITLEMENTS_REQUIRED</code> to <code>NO</code> and <code>AD_HOC_CODE_SIGNING_ALLOWED</code> to <code>YES</code> in your SDKSettings.plist along with setting <code>CODE_SIGNING_REQUIRED</code> to <code>NO</code> in the guide.
Related advice: [[Code Signing]].
 
=== Method 1 - Command line ===
Works with Xcode 6.1 and earlier.
 
From the command line, cd to the Xcode project folder and line run:
<source lang="bash">xcodebuild clean build CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO</source>


The script at [[#Automatically installing apps on your device wirelessly when they are built in Xcode|"Automatically installing apps on your device wirelessly when they are built in Xcode"]] isn't outdated though.
=== Method 2 - SDKSettings.plist modification ===


Related advice: [[Code Signing]].
See [http://www.sysrage.net/guides/ios-programming/building-and-running-ios-applications-without-a-paid-developer-license Building and Running iOS Applications Without A Paid Developer License] for a guide. ''However, that guide is incomplete.'' Make sure to set <code>ENTITLEMENTS_REQUIRED</code> to <code>NO</code> and <code>AD_HOC_CODE_SIGNING_ALLOWED</code> to <code>YES</code> in your SDKSettings.plist along with setting <code>CODE_SIGNING_REQUIRED</code> to <code>NO</code> in the guide.


=== How to test your app on your iOS device without being a member of the Apple Developer program (New & Simple)===
=== Method 3 - other SDKSettings.plist modification ===


Has been tested with Xcode 5.1.1, iOS 7.1 SDK and iPhone 5 running iOS 7.1.
Has been tested with Xcode 5.1.1, iOS 7.1 SDK and iPhone 5 running iOS 7.1.
Line 18: Line 25:
What you need:
What you need:
<li>An app created with Xcode
<li>An app created with Xcode
<li>ldid executable
<li>[[ldid]] executable
<li>SSH or iFile (SSH is recommended)
<li>SSH or iFile (SSH is recommended)
<li>Device needs to be jailbroken
<li>Device needs to be jailbroken
Line 43: Line 50:
2. Build with '''CMD+B''', grab the .app folder from ''~/Library/Developer/Xcode/DerivedData/<ProjectName>/Build/Products/<target>/Your.app'' and copy somewhere like ''~/Documents''.<br />
2. Build with '''CMD+B''', grab the .app folder from ''~/Library/Developer/Xcode/DerivedData/<ProjectName>/Build/Products/<target>/Your.app'' and copy somewhere like ''~/Documents''.<br />
Note: <target> should probably be "'''debug-iphoneos'''"<br /><br />
Note: <target> should probably be "'''debug-iphoneos'''"<br /><br />
Also, if you only want to try the app out yourself, just use AppSync Unified. Or, you can:<br />
a. put AppSync Unified as a requirement for your package or,<br />
b. put the following scripts in a postinst.<br /><br />
(by JJGadgets)<br /><br />
3. Put ldid in the same folder or closeby, navigate to that folder in Terminal and run the following command:<br />
3. Put ldid in the same folder or closeby, navigate to that folder in Terminal and run the following command:<br />
<source lang="bash">./ldid -S Path/To/Your.app/Executable</source>
<source lang="bash">./ldid -S Path/To/Your.app/Executable</source>
Line 61: Line 72:
This should make your app appear on the homescreen. If it doesn't, '''respring''' or '''reboot'''.<br />
This should make your app appear on the homescreen. If it doesn't, '''respring''' or '''reboot'''.<br />


=== Old instructions ===
=== Method 3: Old instructions (obsolete) ===
These steps are designed for the most recent version of Xcode and iOS SDK, but should also work for versions after Xcode 3.2/iPhone SDK 3.x. If for some reason you are stuck with Xcode 3.1.x, try [http://iphonesdkdev.blogspot.com/2009/06/use-xcode-312-to-build-sdk-30-app-to-30.html].
These steps are designed for the most recent version of Xcode and iOS SDK, but should also work for versions after Xcode 3.2/iPhone SDK 3.x. If for some reason you are stuck with Xcode 3.1.x, try [http://iphonesdkdev.blogspot.com/2009/06/use-xcode-312-to-build-sdk-30-app-to-30.html].


Line 89: Line 100:
These steps are necessary for debugging, since the entitlement can no longer be inserted by performing steps 1 – 4. To actually debug your app, make sure you have add <tt>-gta</tt> to '''Other Code Signing Flags''' of your target.
These steps are necessary for debugging, since the entitlement can no longer be inserted by performing steps 1 – 4. To actually debug your app, make sure you have add <tt>-gta</tt> to '''Other Code Signing Flags''' of your target.


* '''5.''' Make sure you have [[ldid]] on your Mac<ref>If not, you can install from [http://pdb.finkproject.org/pdb/package.php/ldid Fink], compile it from git://git.saurik.com/ldid.git, or just download https://github.com/downloads/rpetrich/ldid/ldid.zip. Note that the version from [https://github.com/mxcl/homebrew/blob/master/Library/Formula/ldid.rb homebrew] was outdated!</ref>. Place a copy somewhere e.g. in <tt>/usr/local/bin</tt>.
* '''5.''' Make sure you have [[ldid]] on your Mac<ref>If not, you can install from [http://pdb.finkproject.org/pdb/package.php/ldid Fink], compile it from git://git.saurik.com/ldid.git, download it from https://github.com/downloads/rpetrich/ldid/ldid.zip or install it via [https://github.com/mxcl/homebrew/blob/master/Library/Formula/ldid.rb homebrew]</ref>. Place a copy somewhere e.g. in <tt>/usr/local/bin</tt>.
* '''6.''' Create the a Python script <tt>ldid3.py</tt> right next to the <tt>ldid</tt> program. Make it executable. Fill it with:
* '''6.''' Create the a Python script <tt>ldid3.py</tt> right next to the <tt>ldid</tt> program. Make it executable. Fill it with:
<source lang="python">
<source lang="python">
Line 177: Line 188:


# Verify that the build is for iOS Device and not a Simulator.
# Verify that the build is for iOS Device and not a Simulator.
if [ "$NATIVE_ARCH" != "i386" && "$NATIVE_ARCH" != "x86_64" ]; then
if [[ "$NATIVE_ARCH" != "i386" && "$NATIVE_ARCH" != "x86_64" ]]; then
# Kill any running instances and remove the app folder.
# Kill any running instances and remove the app folder.
ssh root@$IP "killall ${TARGETNAME}; rm -rf /Applications/${WRAPPER_NAME}"
ssh root@$IP "killall ${TARGETNAME}; rm -rf /Applications/${WRAPPER_NAME}"
Line 192: Line 203:
fi
fi
</source>
</source>


== References ==
== References ==

Revision as of 19:15, 25 March 2016

Xcode is the IDE endorsed by Apple for iOS development. The latest stable version is 6.0.1. It comes with the official iOS SDK.

For notes about using Logos and Theos with Xcode, see Xcode Logos.

Developing application without iOS Developer program membership (aka without Provisioning Profile)

To develop for the device, one should first obtain a provisioning profile by joining the iPhone Developer Program (which costs $99). However, some simple tricks can be used to make Xcode compile and debug on jailbroken devices without provisioning profiles.

Related advice: Code Signing.

Method 1 - Command line

Works with Xcode 6.1 and earlier.

From the command line, cd to the Xcode project folder and line run:

xcodebuild clean build CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO

Method 2 - SDKSettings.plist modification

See Building and Running iOS Applications Without A Paid Developer License for a guide. However, that guide is incomplete. Make sure to set ENTITLEMENTS_REQUIRED to NO and AD_HOC_CODE_SIGNING_ALLOWED to YES in your SDKSettings.plist along with setting CODE_SIGNING_REQUIRED to NO in the guide.

Method 3 - other SDKSettings.plist modification

Has been tested with Xcode 5.1.1, iOS 7.1 SDK and iPhone 5 running iOS 7.1.

What you need:

  • An app created with Xcode
  • ldid executable
  • SSH or iFile (SSH is recommended)
  • Device needs to be jailbroken

    Before you start, do this just once:

    Copy /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS*.*.sdk/SDKSettings.plist to your desktop.
    Change

    <key>CODE_SIGNING_REQUIRED</key>
    <string>YES</string>
    

    to

    <key>CODE_SIGNING_REQUIRED</key>
    <string>NO</string>
    

    Save the file, and copy it back into the folder above, replacing the old file (needs admin permissions).
    If you install a major Xcode update, you might need to repeat this process.
    If you just did this and had Xcode open, restart it.

    The actual signing part:

    1. In the top left corner of Xcode, select "iOS Device" as target. Go to build settings, and under Code Signing, select "Don't Code Sign" in every available field.

    2. Build with CMD+B, grab the .app folder from ~/Library/Developer/Xcode/DerivedData/<ProjectName>/Build/Products/<target>/Your.app and copy somewhere like ~/Documents.
    Note: <target> should probably be "debug-iphoneos"

    Also, if you only want to try the app out yourself, just use AppSync Unified. Or, you can:
    a. put AppSync Unified as a requirement for your package or,
    b. put the following scripts in a postinst.

    (by JJGadgets)

    3. Put ldid in the same folder or closeby, navigate to that folder in Terminal and run the following command:

    ./ldid -S Path/To/Your.app/Executable
    

    Note: the executable usually has the same name as the app with no file extension, in this case "Your".
    Also, there should be no output. If you are getting output, for example

    util/ldid.cpp(249): _assert(0:Swap(mach_header_->magic) == MH_MAGIC)<br />
    Trace/BPT trap: 5<br />
    

    then you're doing something wrong and the app won't work.
    Tip: If you're getting "Permission Denied", type

    sudo chmod +x ldid
    

    4. Use SSH, iFunBox or similar to copy the app to /Applications.

    5. In an SSH session, type:

    chmod +x /Applications/Your.app/Your
    

    (the path to the executable)
    Or, open iFile, look for the executable and set permissions to 775 (User: RWE; Group: RWE; World: RE)
    6. In the SSH session, type:

    su mobile -c uicache
    

    This should make your app appear on the homescreen. If it doesn't, respring or reboot.

    Method 3: Old instructions (obsolete)

    These steps are designed for the most recent version of Xcode and iOS SDK, but should also work for versions after Xcode 3.2/iPhone SDK 3.x. If for some reason you are stuck with Xcode 3.1.x, try [1].

    Compiling

    Performing these steps allows you to use Xcode to compile any applications and deploy it yourself.

    • 1. Create a self-signed code-signing certificate with the name “iPhone Developer” on the “login” (default) keychain using Keychain Access[1].
    • 2. Open /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Info.plist (4.2 or below: /Developer/Platforms/iPhoneOS.platform/Info.plist). You may need root permission.
    • 3. Replace all occurrences of XCiPhoneOSCodeSignContext by XCCodeSignContext. There are three of them (XCode Version 3.2.4+).
    • 4. Save the file and restart Xcode.

    or Issue the following commands in terminal:

    #!/bin/bash
    InfoPlist=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Info.plist
    cp $InfoPlist .
    cp Info.plist Info.plist.original
    plutil -convert xml1 Info.plist.original
    sed -e "s/XCiPhoneOSCodeSignContext/XCCodeSignContext/g" Info.plist.original > Info.plist
    plutil -convert binary1 Info.plist
    sudo cp Info.plist InfoPlist
    

    If you upgrade the iOS SDK, you need to perform steps 2 – 4 again.

    Replacing codesign with ldid

    These steps are necessary for debugging, since the entitlement can no longer be inserted by performing steps 1 – 4. To actually debug your app, make sure you have add -gta to Other Code Signing Flags of your target.

    • 5. Make sure you have ldid on your Mac[2]. Place a copy somewhere e.g. in /usr/local/bin.
    • 6. Create the a Python script ldid3.py right next to the ldid program. Make it executable. Fill it with:
    #!/usr/bin/env python
    
    from sys import argv
    from subprocess import check_call
    from os.path import basename, dirname, splitext, join
    from tempfile import NamedTemporaryFile
    
    app = argv[-1]
    ldid_path = join(dirname(__file__), 'ldid')
    obj_path = join(app, splitext(basename(app))[0])
    
    if '-gta' not in argv:
        check_call([ldid_path, '-S', obj_path])
    else:
        with NamedTemporaryFile('w+b', 0) as f:
            f.write("""
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
      <dict>
        <key>get-task-allow</key>
        <true/>
      </dict>
    </plist>
            """)
            check_call([ldid_path, '-S' + f.name, obj_path])
    
    • 7. Open iPhoneCodeSign.xcspec. This file can be found in:
    Xcode version Path
    4.5 - 4.6 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Specifications/iPhoneCodeSign.xcspec
    4.3 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/PrivatePlugIns/iPhoneOS Build System Support.xcplugin/Contents/Resources/iPhoneCodeSign.xcspec
    4.2 /Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/PrivatePlugIns/iPhoneOS Build System Support.xcplugin/Contents/Resources/iPhoneCodeSign.xcspec
    Before 4.2 /Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Plug-ins/iPhoneOS Build System Support.xcplugin/Contents/Resources/iPhoneCodeSign.xcspec
    • 8. Change the entry in the file from calling codesign to ldid3.py. Specifically:
      • Convert the file to a human editable format (esp. in Xcode 4.6 or above). You may skip this if the file is already in plain-text or XML format.
        sudo plutil -convert xml1 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Specifications/iPhoneCodeSign.xcspec
        
      • Replace the entry (which should be near the beginning of the file)
        <key>CommandLine</key><string>/usr/bin/codesign</string>
        
        with
        <key>CommandLine</key><string>/usr/local/bin/ldid3.py</string>
        

    or

    #! /bin/bash
    xcspec=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Specifications/iPhoneCodeSign.xcspec
    cp $xcspec .
    cp iPhoneCodeSign.xcspec iPhoneCodeSign.xcspec.original
    sed -e "s|/usr/bin/codesign|/usr/local/bin/ldid3.py|g" iPhoneCodeSign.xcspec.original > iPhoneCodeSign.xcspec 
    sudo cp iPhoneCodeSign.xcspec $xcspec
    
    • 9. Save the file and restart Xcode.

    If you upgrade the iOS SDK, you need to perform steps 8 – 9 again.

    Allowing apps with invalid signatures to be installed

    These steps allow you to install an unsigned app to the device. This method only works for iOS 4.0 or above.

    • 10. Create a file /var/mobile/tdmtanf on the device, to enable Apple's "TDMTANF bypass" in installd (warning: doing so will also put you in a sandboxed GameCenter[3]).

    If you upgrade the firmware, you need to do step 10 again.


    Automatically installing apps on your device wirelessly when they are built in Xcode

    This is a simple Bash script that installs your app on your jailbroken iOS device whenever you build for iOS Device in Xcode. To set it up, go to Build Phases in your project settings and choose Editor > Add Build Phase > Add Run Script Build Phase in the menu bar. Set your shell to /bin/sh and paste this script in.

    Make sure that you are able to SSH in as root without a password - set up SSH keypairs if you haven't already! Also establish that ldid is installed and in your $PATH.

    #!/bin/sh
    
    # Modify this to your device's IP address.
    IP="192.168.1.109"
    
    # Verify that the build is for iOS Device and not a Simulator.
    if [[ "$NATIVE_ARCH" != "i386" && "$NATIVE_ARCH" != "x86_64" ]]; then
    # Kill any running instances and remove the app folder.
    ssh root@$IP "killall ${TARGETNAME}; rm -rf /Applications/${WRAPPER_NAME}"
    # Self sign the build.
    ldid -S $BUILT_PRODUCTS_DIR/${WRAPPER_NAME}/$TARGETNAME
    # Copy it over.
    scp -r $BUILT_PRODUCTS_DIR/${WRAPPER_NAME} root@$IP:/Applications/
    ssh root@$IP "su -c uicache mobile"
    
    # This part just creates create an OS X notification to let you know that the process is done.
    # You can get terminal-notifier from https://github.com/alloy/terminal-notifier.
    # You can remove this line if you want.
    /Applications/terminal-notifier.app/Contents/MacOS/terminal-notifier -title "Build Complete" -message "${WRAPPER_NAME} installed on ${IP}"
    fi
    

    References