Что некоторые хорошие сценарии XCode должны ускорить разработку?

Нет, это невозможно. Превосходные ответы даны только частично, потому что любой данный метод будет давать ложные срабатывания и ложные отрицания. Даже браузер не всегда знает, присутствует ли сенсорный экран из-за API-интерфейсов ОС, и этот факт может измениться во время сеанса браузера, особенно в случае устройств типа KVM.

См. Дополнительную информацию в этой превосходной статье:

http://www.stucox.com/blog/you-cant-detect-a-touchscreen/

Статья предлагает вам пересмотреть предположения, которые заставляют вас хотеть обнаруживать сенсорные экраны, они, вероятно, ошибочны. (Я проверил свое приложение для своего приложения, и мои предположения были действительно неверны!)

В статье делается вывод:

Для макетов предположим, что у всех есть сенсорный экран. Пользователи мыши могут использовать большие элементы управления пользовательским интерфейсом гораздо легче, чем сенсорные пользователи. То же касается и парящих состояний.

Для событий и взаимодействий, предположим, что у любого может быть сенсорный экран. Реализуйте взаимодействия клавиатуры, мыши и касания друг с другом, чтобы никто не блокировал друг друга.

9
задан xian 4 October 2009 в 02:33
поделиться

6 ответов

Я создал три для моего JSON.Framework для Какао и iPhone . Они заботятся о следующем:

  • Создает образ диска выпуска с динамической встроенной платформой, настраиваемым iPhone SDK, документацией по API и некоторыми файлами документации.
  • Запустите Doxygen поверх источника, чтобы создать Xcode-совместимый набор документации и установить этот. Это означает, что при поиске чего-либо в поиске документации Xcode также можно найти вашу документацию.
  • Запустите Doxygen поверх источника, чтобы обновить зарегистрированную версию документации API в самом дереве исходных текстов. Это довольно удобно, если вы используете Subversion (что предполагается), поскольку документация всегда актуальна для той ветки, в которой вы находитесь. Отлично, например, если вы размещаете на Google Code.

Остерегайтесь жестко запрограммированных значений для конкретного проекта, указанных ниже. Я не хотел потенциально нарушать скрипты, редактируя их. Они запускаются из фазы пользовательского сценария в Xcode. Вы можете увидеть, как они интегрированы в проект Xcode для проекта, указанного выше.

CreateDiskImage.sh:

#!/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

InstallDocumentation.sh:

#!/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

RegenerateDocumentation.sh:

#!/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
4
ответ дан 2 November 2019 в 23:09
поделиться

Здесь можно регистрировать метод и его аргументы при каждом его выполнении (выберите определение метода через ложь с открывающей скобкой и выполните сценарий). Если в выводе отображается FIXME, это означает, что это нераспознанный тип. Вы можете либо добавить его в сценарий, либо выбрать соответствующий спецификатор формата вручную.

#!/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),
2
ответ дан 2 November 2019 в 23:09
поделиться

Здесь можно создать метод -описание для класса. Выделите раздел объявления переменных экземпляра (@interface ... {...}) и выполните сценарий. Затем вставьте результат в свою реализацию. Я использую его вместе с po objectName в GDB. Если в выводе появляется FIXME, значит, это ' нераспознанный тип. Вы можете добавить его в сценарий или выбрать соответствующий спецификатор формата вручную.

#!/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),
2
ответ дан 2 November 2019 в 23:09
поделиться

Вот один, который я где-то нашел, который создает директивы свойств @property (copy) и @synthesize для переменной экземпляра. Можно было бы немного улучшить (например, позволить вам синтезировать несколько переменных одновременно), но это лучше, чем создавать их вручную.

Выберите переменную экземпляра, для которой вы хотите создать свойство, и активируйте скрипт.

Если я хочу (сохранить) вместо (копировать), я просто активирую сценарий и изменю его, чтобы сохранить вручную (достаточно умен, чтобы не включать (копию) в примитивные типы, такие как 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;
1
ответ дан 2 November 2019 в 23:09
поделиться

Это улучшение сценария "Create Property and Synths for Synths example variables", который Лоуренс Джонстон поместил выше.

Settings:

Input: Весь документ Справочник: Главный каталог Выход: Выбрасываемый выход Ошибки: Игнорировать ошибки (или Предупреждать, если вы хотите их видеть)

Выберите любое количество переменных, и он создаст свойства и синтаксис для всех из них. Он даже создаст/редактирует ваш метод dalloc по мере необходимости.

Редактирование результатов, если они не совсем верны (copy vs. retain и т.д.)

Обрабатывает больше вещей, таких как имя, поведение, dealloc,...

Ссылка на то, откуда это исходит, и обсуждение: 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;
4
ответ дан 2 November 2019 в 23:09
поделиться

Это создает для вас @proptery, @synthesize, dealloc, viewDidUnload и общедоступные методы. Простая интеграция с XCode:

http://github.com/holtwick/xobjc

0
ответ дан 2 November 2019 в 23:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: