Search code examples
iphoneiosxcodexcodebuild

Converting a xcodeproj in-app purchase to a pkg file from terminal (Bash) or how to convert a xcarchive file to a pkg file?


I am trying to create a bash script to automate the creation of in-app purchase pkg files.

I am at a point that the script creates successfully all in-app purchase xcodeproj projects and then archive them using this command

xcodebuild -scheme $nameOfProject archive

$nameOfProject is a variable that holds, inside a loop, the name of the xcodeproj file correspondent to the in-app purchase.

After doing this, I have to open the archive part of Xcode and manually export all archives to create the pkg files that I need to have to upload to iTC.

Is there any command that I can use to do this automatically from terminal?

Another thing that would provide the same solution would be: how to convert a xcarchive file into a pkg file?


Solution

  • After some googling and some testing with the "In-app purchase content" Project, I think that what you need to use is the productbuild command line tool. Since I am only iOS developer myself, I have no experience with creating installers but I am pretty sure the "pkg" file for the in-app content is created using this command line tools.

    To find the correct parameters you can refer to https://developer.apple.com/library/mac/#documentation/ToolsLanguages/Conceptual/OSXWorkflowGuide/DistributingApplications/DistributingApplications.html#//apple_ref/doc/uid/TP40011201-CH5-SW1

    or man.

    Edit:
    To test what XCode does, I have created a simple project
    Project

    And I archived it: Archive contents

    Then I created a simple program, let's call it ArgumentLogger, the code is

    int main(int argc, const char* argv[]) {
        //Open a file for logging 
        FILE* file = fopen("/Users/Sulthan/Desktop/log.txt","a+");
    
        for (int i = 0; i < argc; i++) {
            //log all parameters
            fprintf(file, "%s\n", argv[i]);
        }
    
        //end
        fclose(file);
        return 0;
    }
    

    Let's have an example - for bash command:

    ArgumentLoggger --arg test1 test2 test3
    

    log.txt will contain

    ArgumentLogger
    --arg
    test1
    test2
    test3
    

    Now, let's replace /usr/bin/productbuild with this program

    sudo mv /usr/bin/productbuild /usr/bin/productbuild_old
    sudo mv ArgumentLogger /usr/bin/productbuild
    

    and then hit "Distribute" in XCode. Distribute and export the package.

    log.txt now contains

    /usr/bin/productbuild
    --content
    /var/folders/v5/wwrmfpqx2mx1q5sf67_6vgg00000gn/T/FDCEA38E-1EF6-490B-8C30-8B0675C56CC8-47322-00014822C462D3CD/TestContent
    /var/folders/v5/wwrmfpqx2mx1q5sf67_6vgg00000gn/T/FDCEA38E-1EF6-490B-8C30-8B0675C56CC8-47322-00014822C462D3CD/TestContent.pkg
    

    Now we see exactly what XCode did.

    The second file is the resulting file, I am not sure whether there is something more done with the file or not, but after expanding it with pkgutil, the contents seem to be the same as the ones in the pkg created from XCode.

    The first file is a directory which seems to be taken directly from the xcarchive file. Let's see its contents
    Temp dir contents

    Edit 2:
    In summary, the bash script should be something along the lines of:

    CONTENTS_DIR = $( find "$nameOfProject.xcarchive" -name "InAppPurchaseContent" -type d )
    PKG_FILE = "$nameOfProject.pkg"
    
    productbuild --content "$CONTENTS_DIR" "$PKG_FILE"