代码之家  ›  专栏  ›  技术社区  ›  Redwood

有哪些好的Xcode脚本可以加速开发?

  •  9
  • Redwood  · 技术社区  · 16 年前

    Xcode允许您创建用于执行重复任务的自动化脚本。你写了哪些脚本来加速开发?

    6 回复  |  直到 16 年前
        1
  •  4
  •   Stig Brautaset    16 年前

    JSON.Framework for Cocoa and the iPhone

    • 在源代码上运行Doxygen,以更新源代码树本身中API文档的签入版本。如果你使用Subversion(它假设),这非常整洁,因为你所在的分支的文档总是最新的。例如,如果你在谷歌代码上托管,那就太好了。

    #!/bin/sh
    
    set -x
    
    # Determine the project name and version
    VERS=$(agvtool mvers -terse1)
    
    # Derived names
    VOLNAME=${PROJECT}_${VERS}
    DISK_IMAGE=$BUILD_DIR/$VOLNAME
    DISK_IMAGE_FILE=$INSTALL_DIR/$VOLNAME.dmg
    
    # Remove old targets
    rm -f $DISK_IMAGE_FILE
    test -d $DISK_IMAGE && chmod -R +w $DISK_IMAGE && rm -rf $DISK_IMAGE
    mkdir -p $DISK_IMAGE
    
    # Create the Embedded framework and copy it to the disk image.
    xcodebuild -target JSON -configuration Release install || exit 1
    cp -p -R $INSTALL_DIR/../Frameworks/$PROJECT.framework $DISK_IMAGE
    
    IPHONE_SDK=2.2.1
    
    # Create the iPhone SDK directly in the disk image folder.
    xcodebuild -target libjson -configuration Release -sdk iphoneos$IPHONE_SDK install \
        ARCHS=armv6 \
        DSTROOT=$DISK_IMAGE/SDKs/JSON/iphoneos.sdk || exit 1
    sed -e "s/%PROJECT%/$PROJECT/g" \
        -e "s/%VERS%/$VERS/g" \
        -e "s/%IPHONE_SDK%/$IPHONE_SDK/g" \
        $SOURCE_ROOT/Resources/iphoneos.sdk/SDKSettings.plist > $DISK_IMAGE/SDKs/JSON/iphoneos.sdk/SDKSettings.plist || exit 1
    
    xcodebuild -target libjson -configuration Release -sdk iphonesimulator$IPHONE_SDK install \
        ARCHS=i386 \
        DSTROOT=$DISK_IMAGE/SDKs/JSON/iphonesimulator.sdk || exit 1
    sed -e "s/%PROJECT%/$PROJECT/g" \
        -e "s/%VERS%/$VERS/g" \
        -e "s/%IPHONE_SDK%/$IPHONE_SDK/g" \
        $SOURCE_ROOT/Resources/iphonesimulator.sdk/SDKSettings.plist > $DISK_IMAGE/SDKs/JSON/iphonesimulator.sdk/SDKSettings.plist || exit 1    
    
    # Allow linking statically into normal OS X apps
    xcodebuild -target libjson -configuration Release -sdk macosx10.5 install \
        DSTROOT=$DISK_IMAGE/SDKs/JSON/macosx.sdk || exit 1
    
    # Copy the source verbatim into the disk image.
    cp -p -R $SOURCE_ROOT/Source $DISK_IMAGE/$PROJECT
    rm -rf $DISK_IMAGE/$PROJECT/.svn
    
    # Create the documentation
    xcodebuild -target Documentation -configuration Release install || exit 1
    cp -p -R $INSTALL_DIR/Documentation/html $DISK_IMAGE/Documentation
    rm -rf $DISK_IMAGE/Documentation/.svn
    
    cat <<HTML > $DISK_IMAGE/Documentation.html
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <script type="text/javascript">
    <!--
    window.location = "Documentation/index.html"
    //-->
    </script>
    </head>
    <body>
    <p>Aw, shucks! I tried to redirect you to the <a href="Documentaton/index.html">api documentation</a> but obviously failed. Please find it yourself. </p>
    </body>
    </html>
    HTML
    
    cp -p $SOURCE_ROOT/README $DISK_IMAGE
    cp -p $SOURCE_ROOT/Credits.rtf $DISK_IMAGE
    cp -p $SOURCE_ROOT/Install.rtf $DISK_IMAGE
    cp -p $SOURCE_ROOT/Changes.rtf $DISK_IMAGE
    
    hdiutil create -fs HFS+ -volname $VOLNAME -srcfolder $DISK_IMAGE $DISK_IMAGE_FILE
    

    #!/bin/sh
    # See also http://developer.apple.com/tools/creatingdocsetswithdoxygen.html 
    
    set -x
    
    VERSION=$(agvtool mvers -terse1)
    
    DOXYFILE=$DERIVED_FILES_DIR/doxygen.config
    DOXYGEN=/Applications/Doxygen.app/Contents/Resources/doxygen
    DOCSET=$INSTALL_DIR/Docset
    
    rm -rf $DOCSET
    mkdir -p $DOCSET || exit 1
    mkdir -p $DERIVED_FILES_DIR || exit 1
    
    if ! test -x $DOXYGEN ; then
        echo "*** Install Doxygen to get documentation generated for you automatically ***"
        exit 1
    fi
    
    # Create a doxygen configuration file with only the settings we care about
    $DOXYGEN -g - > $DOXYFILE
    
    cat <<EOF >> $DOXYFILE
    
    PROJECT_NAME           = $FULL_PRODUCT_NAME
    PROJECT_NUMBER         = $VERSION
    OUTPUT_DIRECTORY       = $DOCSET
    INPUT                  = $SOURCE_ROOT/Source
    FILE_PATTERNS          = *.h *.m
    
    HIDE_UNDOC_MEMBERS     = YES
    HIDE_UNDOC_CLASSES     = YES
    HIDE_UNDOC_RELATIONS   = YES
    REPEAT_BRIEF           = NO
    CASE_SENSE_NAMES       = YES
    INLINE_INHERITED_MEMB  = YES
    SHOW_FILES             = NO
    SHOW_INCLUDE_FILES     = NO
    GENERATE_LATEX         = NO
    GENERATE_HTML          = YES
    GENERATE_DOCSET        = YES
    DOCSET_FEEDNAME        = "$PROJECT.framework API Documentation"
    DOCSET_BUNDLE_ID       = org.brautaset.$PROJECT
    
    EOF
    
    #  Run doxygen on the updated config file.
    #  doxygen creates a Makefile that does most of the heavy lifting.
    $DOXYGEN $DOXYFILE
    
    #  make will invoke docsetutil. Take a look at the Makefile to see how this is done.
    make -C $DOCSET/html install
    
    #  Construct a temporary applescript file to tell Xcode to load a docset.
    rm -f $TEMP_DIR/loadDocSet.scpt
    
    cat <<EOF > $TEMP_DIR/loadDocSet.scpt
    tell application "Xcode"
        load documentation set with path "/Users/$USER/Library/Developer/Shared/Documentation/DocSets/org.brautaset.${PROJECT}.docset/"
    end tell
    EOF
    
    # Run the load-docset applescript command.
    osascript $TEMP_DIR/loadDocSet.scpt
    

    #!/bin/sh
    # See also http://developer.apple.com/tools/creatingdocsetswithdoxygen.html 
    
    set -x
    
    VERSION=$(agvtool mvers -terse1)
    
    DOXYFILE=$DERIVED_FILES_DIR/doxygen.config
    DOXYGEN=/Applications/Doxygen.app/Contents/Resources/doxygen
    DOCSET=$INSTALL_DIR/Documentation
    APIDOCDIR=$SOURCE_ROOT/documentation
    
    rm -rf $DOCSET
    mkdir -p $DOCSET || exit 1
    mkdir -p $DERIVED_FILES_DIR || exit 1
    
    if ! test -x $DOXYGEN ; then
        echo "*** Install Doxygen to get documentation generated for you automatically ***"
        exit 1
    fi
    
    # Create a doxygen configuration file with only the settings we care about
    $DOXYGEN -g - > $DOXYFILE
    
    cat <<EOF >> $DOXYFILE
    
    PROJECT_NAME           = $FULL_PRODUCT_NAME
    PROJECT_NUMBER         = $VERSION
    OUTPUT_DIRECTORY       = $DOCSET
    INPUT                  = $SOURCE_ROOT/Source
    FILE_PATTERNS          = *.h *.m
    
    HIDE_UNDOC_MEMBERS     = YES
    HIDE_UNDOC_CLASSES     = YES
    HIDE_UNDOC_RELATIONS   = YES
    REPEAT_BRIEF           = NO
    CASE_SENSE_NAMES       = YES
    INLINE_INHERITED_MEMB  = YES
    SHOW_FILES             = NO
    SHOW_INCLUDE_FILES     = NO
    GENERATE_LATEX         = NO
    GENERATE_HTML          = YES
    GENERATE_DOCSET        = NO
    
    EOF
    
    #  Run doxygen on the updated config file.
    $DOXYGEN $DOXYFILE
    
    # Replace the old dir with the newly generated one.
    rm -f $APIDOCDIR/*
    cp -p $DOCSET/html/* $APIDOCDIR
    cd $APIDOCDIR
    
    # Revert files that differ only in the timestamp.
    svn diff *.html | diffstat | awk '$3 == 2 { print $1 }' | xargs svn revert
    
    # Add/remove files from subversion.
    svn st | awk '
        $1 == "?" { print "svn add", $2 }
        $1 == "!" { print "svn delete",  $2 }
    ' | sh -
    
    svn propset svn:mime-type text/html *.html
    svn propset svn:mime-type text/css *.css
    svn propset svn:mime-type image/png *.png
    svn propset svn:mime-type image/gif *.gif
    
        2
  •  4
  •   David Whatley    16 年前

    输出:丢弃输出

    如果结果不完全正确,请编辑(复制与保留等)

    http://cocoawithlove.com/2008/12/instance-variable-to-synthesized.html

    #! /usr/bin/perl -w
    
    #  Created by Matt Gallagher on 20/10/08.
    #  Copyright 2008 Matt Gallagher. All rights reserved.
    #
    #  Enhancements by Yung-Luen Lan and Mike Schrag on 12/08/09.
    #  (mainly: multiple lines)
    #  Copyright 2009 Yung-Luen Lan and Mike Schrag. All rights reserved.
    #
    #  Enhancements by Pierre Bernard on 20/09/09.
    #  (mainly: underbar storage name, behavior, dealloc,…)
    #  Copyright 2009 Pierre Bernard. All rights reserved.
    #
    #  Permission is given to use this source code file without charge in any
    #  project, commercial or otherwise, entirely at your risk, with the condition
    #  that any redistribution (in part or whole) of source code must retain
    #  this copyright and permission notice. Attribution in compiled projects is
    #  appreciated but not required.
    
    use strict;
    
    # Get the header file contents from Xcode user scripts
    my $headerFileContents = <<'HEADERFILECONTENTS';
    %%%{PBXAllText}%%%
    HEADERFILECONTENTS
    
    # Get the indices of the selection from Xcode user scripts
    my $selectionStartIndex = %%%{PBXSelectionStart}%%%;
    my $selectionEndIndex = %%%{PBXSelectionEnd}%%%;
    
    
    
    # Find the closing brace (end of the class variables section)
    my $remainderOfHeader = substr $headerFileContents, $selectionEndIndex;
    my $indexAfterClosingBrace = $selectionEndIndex + index($remainderOfHeader, "\n}\n") + 3;
    if ($indexAfterClosingBrace == -1)
    {
     exit 1;
    }
    
    
    # Get path of the header file
    my $implementationFilePath = "%%%{PBXFilePath}%%%";
    my $headerFilePath = $implementationFilePath;
    
    # Look for an implemenation file with a ".m" or ".mm" extension
    $implementationFilePath =~ s/\.[hm]*$/.m/;
    if (!(-e $implementationFilePath))
    {
     $implementationFilePath =~ s/.m$/.mm/;
    }
    
    # Stop now if the implementation file can't be found
    if (!(-e $implementationFilePath))
    {
     exit 1;
    }
    
    
    my $propertyDeclarations = '';
    my $synthesizeStatements = '';
    my $releaseStatements = '';
    
    
    
    # Handle subroutine to trim whitespace off both ends of a string
    sub trim
    {
     my $string = shift;
     $string =~ s/^\s*(.*?)\s*$/$1/;
     return $string;
    }
    
    # Get the selection out of the header file
    my $selectedText =  substr $headerFileContents, $selectionStartIndex, ($selectionEndIndex - $selectionStartIndex);
    $selectedText = trim $selectedText;
    
    my $selectedLine;
    
    foreach $selectedLine (split(/\n+/, $selectedText)) {
     my $type = '';
     my $asterisk = '';
     my $name = '';
     my $behavior = '';
    
     # Test that the selection is:
     #  At series of identifiers (the type name and access specifiers)
     #  Possibly an asterisk
     #  Another identifier (the variable name)
     #  A semi-colon
     if (length($selectedLine) && ($selectedLine =~ /([_A-Za-z][_A-Za-z0-9]*\s*)+([\s\*]+)([_A-Za-z][_A-Za-z0-9]*);/))
     {
      $type = $1;
      $type = trim $type;
      $asterisk = $2;
      $asterisk = trim $asterisk;
      $name = $3;
      $behavior = 'assign';
    
      if (defined($asterisk) && length($asterisk) == 1)
      {
       if (($type eq 'NSString') || ($type eq 'NSArray') || ($type eq 'NSDictionary') || ($type eq 'NSSet'))
       {
        $behavior = 'copy';
       }
       else
       {
        if (($name =~ /Delegate/) || ($name =~ /delegate/) || ($type =~ /Delegate/) || ($type =~ /delegate/))
        {
         $behavior = 'assign';
        }
        else
        {
         $behavior = 'retain';
        }
       }
      }
      else
      {
       if ($type eq 'id')
       {
        $behavior = 'copy';
       }
    
       $asterisk = '';
      }
     }
     else
     {
      next;
     }
    
     my $storageName = '';
    
     if ($name =~ /_([_A-Za-z][_A-Za-z0-9]*)/) {
      $storageName = $name;
      $name = $1;  
     }
    
    
     # Create and insert the propert declaration
     my $propertyDeclaration = "\@property (nonatomic, $behavior) $type " . $asterisk . $name . ";\n";
    
     $propertyDeclarations = $propertyDeclarations . $propertyDeclaration;
    
    
    
     # Create and insert the synthesize statement 
     my $synthesizeStatement = '';
    
     if (length($storageName))
     {
      $synthesizeStatement = "\@synthesize $name = $storageName;\n";
     }
     else
     {
      $synthesizeStatement =  "\@synthesize $name;\n";
     }
    
     $synthesizeStatements = $synthesizeStatements . $synthesizeStatement;
    
    
    
     # Create and insert release statement  
     my $releaseName = $name;
     my $releaseStatement = '';  
    
     if (length($storageName))
     {
      $releaseName = $storageName;  
     }
    
     if ($behavior eq 'assign')
     {
      if ($type eq 'SEL')
      {
       $releaseStatement = "\t$releaseName = NULL;\n";  
      }
     }
     else 
     {
      $releaseStatement = "\t[$releaseName release];\n\t$releaseName = nil;\n";  
     }
    
     $releaseStatements = $releaseStatements . $releaseStatement;
    }
    
    my $leadingNewline = '';
    my $trailingNewline = '';
    
    # Determine if we need to add a newline in front of the property declarations
    if (substr($headerFileContents, $indexAfterClosingBrace, 1) eq "\n")
    {
     $indexAfterClosingBrace += 1;
     $leadingNewline = '';
    }
    else
    {
     $leadingNewline = "\n";
    }
    
    # Determine if we need to add a newline after the property declarations
    if (substr($headerFileContents, $indexAfterClosingBrace, 9) eq '@property')
    {
     $trailingNewline = '';
    }
    else
    {
     $trailingNewline = "\n";
    }
    
    substr($headerFileContents, $indexAfterClosingBrace, 0) = $leadingNewline . $propertyDeclarations . $trailingNewline;
    
    my $replaceFileContentsScript = <<'REPLACEFILESCRIPT';
    on run argv
     set fileAlias to POSIX file (item 1 of argv)
     set newDocText to (item 2 of argv)
     tell application "Xcode"
      set doc to open fileAlias
      set text of doc to (text 1 thru -2 of newDocText)
     end tell
    end run
    REPLACEFILESCRIPT
    
    # Use Applescript to replace the contents of the header file
    # (I could have used the "Output" of the Xcode user script instead)
    system 'osascript', '-e', $replaceFileContentsScript, $headerFilePath, $headerFileContents;
    
    
    
    my $getFileContentsScript = <<'GETFILESCRIPT';
    on run argv
     set fileAlias to POSIX file (item 1 of argv)
     tell application "Xcode"
      set doc to open fileAlias
      set docText to text of doc
     end tell
     return docText
    end run
    GETFILESCRIPT
    
    # Get the contents of the implmentation file
    open(SCRIPTFILE, '-|') || exec 'osascript', '-e', $getFileContentsScript, $implementationFilePath;
    my $implementationFileContents = do {local $/; <SCRIPTFILE>};
    close(SCRIPTFILE);
    
    # Look for the class implementation statement
    if (length($implementationFileContents) && ($implementationFileContents =~ /(\@implementation [_A-Za-z][_A-Za-z0-9]*\n)/))
    {
     my $matchString = $1;
     my $indexAfterMatch = index($implementationFileContents, $matchString) + length($matchString);
    
     # Determine if we want a newline before the synthesize statement
     if (substr($implementationFileContents, $indexAfterMatch, 1) eq "\n")
     {
      $indexAfterMatch += 1;
      $leadingNewline = '';
     }
     else
     {
      $leadingNewline = "\n";
     }
    
     # Determine if we want a newline after the synthesize statement
     if (substr($implementationFileContents, $indexAfterMatch, 11) eq '@synthesize')
     {
      $trailingNewline = '';
     }
     else 
     {
      $trailingNewline = "\n";
     }
    
     substr($implementationFileContents, $indexAfterMatch, 0) = $leadingNewline. $synthesizeStatements . $trailingNewline;
    
     if ($implementationFileContents =~ /([ \t]*\[.*super.*dealloc.*\].*;.*\n)/)
     {  
      my $deallocMatch = $1;  
      my $indexAfterDeallocMatch = index($implementationFileContents, $deallocMatch);  
    
      substr($implementationFileContents, $indexAfterDeallocMatch, 0) = "$releaseStatements\n";  
    
     }
     elsif ($implementationFileContents =~ /(\@synthesize .*\n)*(\@synthesize [^\n]*\n)/s) {  
      my $synthesizeMatch = $2;  
       my $indexAfterSynthesizeMatch = index($implementationFileContents, $synthesizeMatch) + length($synthesizeMatch);  
      my $deallocMethod = "\n- (void)dealloc\n{\n$releaseStatements\n\t[super dealloc];\n}\n";  
    
      substr($implementationFileContents, $indexAfterSynthesizeMatch, 0) = $deallocMethod;  
     }
    
     # Use Applescript to replace the contents of the implementation file in Xcode
     system 'osascript', '-e', $replaceFileContentsScript, $implementationFilePath, $implementationFileContents;
    }
    
    exit 0;
    
        3
  •  2
  •   Redwood    16 年前

    #!/usr/bin/python
    
    # LogMethod
    # Selection
    # Selection
    # Insert after Selection
    # Display in Alert
    
    import sys
    import re
    
    input = sys.stdin.read()
    
    methodPieces = re.findall("""(\w*:)""", input)
    vars = re.findall(""":\(([^)]*)\)[ ]?(\w*)""", input)
    
    outputStrings = ["\n  NSLog(@\""]
    
    # Method taking no parameters
    if not methodPieces:
        outputStrings.append(re.findall("""(\w*)[ ]?{""", input)[0])
    
    for (methodPiece, var) in zip(methodPieces, vars):
        type = var[0]
        outputStrings.append(methodPiece)
        if "**" in type:
            outputStrings.append("%p")
        elif "*" in type:
            if "char" in type:
                outputStrings.append("%c")
            else:
                outputStrings.append("%@")
        else:
            if "int" in type or "NSInteger" in type or "BOOL" in type:
                outputStrings.append("%i")
            elif "NSUInteger" in type:
                outputStrings.append("%u")
            elif "id" in type:
                outputStrings.append("%@")
            elif "NSTimeInterval" in type:
                outputStrings.append("%f")
            elif "SEL" in type:
                outputString.append("%s")
            else:
                outputStrings.append('"FIXME"')
        if not methodPiece == methodPieces[-1]:
            outputStrings.append('\\n"\n         @"')
    
    outputStrings.append("\"")
    
    for var in vars:
        name = var[1]
        outputStrings.append(",\n         ")
        outputStrings.append(name)
    
    outputStrings.append(");")
    
    print "".join(outputStrings),
    
        4
  •  2
  •   Redwood    16 年前

    这里有一个为类创建-description方法的方法。突出显示实例变量声明部分(@interface…{…})并执行脚本。然后将结果粘贴到您的实现中。我把这个和 po objectName

    #!/usr/bin/python
    
    # Create description method for class
    # Selection
    # Selection
    # Insert after Selection
    # Display in Alert
    
    import sys
    import re
    
    input = sys.stdin.read()
    
    className = re.findall("""(?:@interface )(\w*)""", input)[0]
    vars = re.findall("""(\w*[ ][*]?)(\w*?)_?;""", input)
    
    outputStrings = ["- (NSString *)description {\n"]
    outputStrings.append("""return [NSString stringWithFormat:@"%s :\\n"\n@"  -""" % className)
    
    for type, var in vars:
        outputStrings.append("%s:" % var)
        if "**" in type:
            outputStrings.append("%p")
        elif "*" in type:
            if "char" in type:
                outputStrings.append("%c")
            else:
                outputStrings.append("%@")
        else:
            if "int" in type or "NSInteger" in type or "BOOL" in type:
                outputStrings.append("%i")
            elif "NSUInteger" in type:
                outputStrings.append("%u")
            elif "id" in type:
                outputStrings.append("%@")
            elif "NSTimeInterval" in type:
                outputStrings.append("%f")
            elif "SEL" in type:
                outputString.append("%s")
            else:
                outputStrings.append('"FIXME"')
    
        if not var == vars[-1][1]:
            outputStrings.append(',\\n"\n@"  -')
    
    outputStrings.append("\"")
    
    for type, var in vars:
        outputStrings.append(",\n")
        outputStrings.append("[self %s]" % var)
    
    outputStrings.append("];\n}")
    
    print "".join(outputStrings),
    
        5
  •  1
  •   Redwood    16 年前

    选择要为其创建属性的实例变量并激活脚本。

    int

    #! /usr/bin/perl -w
    
    #Create property from instance variable
    
    #Entire Document
    #Home Directory
    #Discard Output
    #Display in Alert
    
    use strict;
    
    # Get the header file contents from Xcode user scripts
    my $headerFileContents = <<'HEADERFILECONTENTS';
    %%%{PBXAllText}%%%
    HEADERFILECONTENTS
    
    # Get the indices of the selection from Xcode user scripts
    my $selectionStartIndex = %%%{PBXSelectionStart}%%%;
    my $selectionEndIndex = %%%{PBXSelectionEnd}%%%;
    
    # Get path of the header file
    my $implementationFilePath = "%%%{PBXFilePath}%%%";
    my $headerFilePath = $implementationFilePath;
    
    # Look for an implemenation file with a ".m" or ".mm" extension
    $implementationFilePath =~ s/\.[hm]*$/.m/;
    if (!(-e $implementationFilePath))
    {
        $implementationFilePath =~ s/.m$/.mm/;
    }
    
    # Handle subroutine to trime whitespace off both ends of a string
    sub trim
    {
        my $string = shift;
        $string =~ s/^\s*(.*?)\s*$/$1/;
        return $string;
    }
    
    # Get the selection out of the header file
    my $selectedText =  substr $headerFileContents, $selectionStartIndex, ($selectionEndIndex - $selectionStartIndex);
    $selectedText = trim $selectedText;
    
    my $type = "";
    my $asterisk = "";
    my $name = "";
    my $behavior = "";
    
    # Test that the selection is:
    #  At series of identifiers (the type name and access specifiers)
    #  Possibly an asterisk
    #  Another identifier (the variable name)
    #  A semi-colon
    if (length($selectedText) && ($selectedText =~ /([_A-Za-z][_A-Za-z0-9]*\s*)+([\s\*]+)([_A-Za-z][_A-Za-z0-9]*);/))
    {
        $type = $1;
        $type = trim $type;
        $asterisk = $2;
        $asterisk = trim $asterisk;
        $name = $3;
        $behavior = "";
        if (defined($asterisk) && length($asterisk) == 1)
        {
            $behavior = "(copy) "; #"(nonatomic, retain) ";
        }
        else
        {
            $asterisk = "";
        }
    }
    else
    {
        exit 1;
    }
    
    # Find the closing brace (end of the class variables section)
    my $remainderOfHeader = substr $headerFileContents, $selectionEndIndex;
    my $indexAfterClosingBrace = $selectionEndIndex + index($remainderOfHeader, "\n}\n") + 3;
    if ($indexAfterClosingBrace == -1)
    {
        exit 1;
    }
    
    # Determine if we need to add a newline in front of the property declaration
    my $leadingNewline = "\n";
    if (substr($headerFileContents, $indexAfterClosingBrace, 1) eq "\n")
    {
        $indexAfterClosingBrace += 1;
        $leadingNewline = "";
    }
    
    # Determine if we need to add a newline after the property declaration
    my $trailingNewline = "\n";
    if (substr($headerFileContents, $indexAfterClosingBrace, 9) eq "\@property")
    {
        $trailingNewline = "";
    }
    
    # Create and insert the propert declaration
    my $propertyDeclaration = $leadingNewline . "\@property " . $behavior . $type . " " . $asterisk . $name . ";\n" . $trailingNewline;
    substr($headerFileContents, $indexAfterClosingBrace, 0) = $propertyDeclaration;
    
    my $replaceFileContentsScript = <<'REPLACEFILESCRIPT';
    on run argv
        set fileAlias to POSIX file (item 1 of argv)
        set newDocText to (item 2 of argv)
        tell application "Xcode"
            set doc to open fileAlias
            set text of doc to newDocText
        end tell
    end run
    REPLACEFILESCRIPT
    
    # Use Applescript to replace the contents of the header file
    # (I could have used the "Output" of the Xcode user script instead)
    system 'osascript', '-e', $replaceFileContentsScript, $headerFilePath, $headerFileContents;
    
    # Stop now if the implementation file can't be found
    if (!(-e $implementationFilePath))
    {
        exit 1;
    }
    
    my $getFileContentsScript = <<'GETFILESCRIPT';
    on run argv
        set fileAlias to POSIX file (item 1 of argv)
        tell application "Xcode"
            set doc to open fileAlias
            set docText to text of doc
        end tell
        return docText
    end run
    GETFILESCRIPT
    
    # Get the contents of the implmentation file
    open(SCRIPTFILE, '-|') || exec 'osascript', '-e', $getFileContentsScript, $implementationFilePath;
    my $implementationFileContents = do {local $/; <SCRIPTFILE>};
    close(SCRIPTFILE);
    
    # Look for the class implementation statement
    if (length($implementationFileContents) && ($implementationFileContents =~ /(\@implementation [_A-Za-z][_A-Za-z0-9]*\n)/))
    {
        my $matchString = $1;
        my $indexAfterMatch = index($implementationFileContents, $matchString) + length($matchString);
    
        # Determine if we want a newline before the synthesize statement
        $leadingNewline = "\n";
        if (substr($implementationFileContents, $indexAfterMatch, 1) eq "\n")
        {
            $indexAfterMatch += 1;
            $leadingNewline = "";
        }
    
        # Determine if we want a newline after the synthesize statement
        $trailingNewline = "\n";
        if (substr($implementationFileContents, $indexAfterMatch, 11) eq "\@synthesize")
        {
            $trailingNewline = "";
        }
    
        # Create and insert the synthesize statement 
        my $synthesizeStatement = $leadingNewline . "\@synthesize " . $name . ";\n" . $trailingNewline;
        substr($implementationFileContents, $indexAfterMatch, 0) = $synthesizeStatement;
    
        # Use Applescript to replace the contents of the implementation file in Xcode
        system 'osascript', '-e', $replaceFileContentsScript, $implementationFilePath, $implementationFileContents;
    }
    
    exit 0;
    
        6
  •  0
  •   Holtwick    15 年前