3

私の問題は設計によるものかもしれないと推測していますが、回避策があることを願っています。

私のアプリは基本的にドキュメント リーダーです。コンパイル時に多数の PDF が取り込まれ、アプリにバンドルされます。アプリが最初に実行されると、それらはコピーされ(ユーザーが注釈を追加するためなど)、UITableViewのDictを生成します(PDFメタデータを使用してタイトルなどを入力します)。アプリの新しいバージョンがリリースされたら、アップグレード プロセス中にファイルをコピーすることについてもう少し賢くしたいと思います。現在、私にできる最善のことは、すべてを消去して新たにコピーすることです。

問題は、コンパイル中にXcodeがファイルをバンドルにコピーすると、NSFileCreationDateとNSFileModificationDateの両方がアプリのコンパイル時にリセットされるように見えることです。これにより、基本的に日付チェック全体が役に立たなくなります。

2012-10-11 15:19:29.254 handouts[5131:707] File attributes of source: {
NSFileCreationDate = "2012-10-11 19:19:10 +0000";
NSFileExtensionHidden = 0;
NSFileGroupOwnerAccountID = 501;
NSFileGroupOwnerAccountName = mobile;
NSFileModificationDate = "2012-10-11 19:19:10 +0000";
NSFileOwnerAccountID = 501;
NSFileOwnerAccountName = mobile;
NSFilePosixPermissions = 420;
NSFileProtectionKey = NSFileProtectionNone;
NSFileReferenceCount = 1;
NSFileSize = 466028;
NSFileSystemFileNumber = 2754117;
NSFileSystemNumber = 234881027;
NSFileType = NSFileTypeRegular;

}

私は現在、ファイルサイズと日付を組み合わせて使用​​することを計画していますが、非常に面倒で非常に速くなると想像しています. そして、大量のメタデータを自分で追跡する必要があります。私は何か間違ったことをしていますか?Xcode がコピーしているファイルのタイムスタンプを尊重するようにする方法はありますか?

if...then私が書いている可能性が高いコードスープに深く入り込む前に、チェックしておこうと思いました。ありがとう!

4

1 に答える 1

0

私の知る限り、XCodeに日付を保持させる方法はありません。同様の問題に遭遇し、ディレクトリ内のファイルの変更日を (再帰的に) 含む plist ファイルを作成するシェル スクリプトを思いつきました。次に、それをバンドルに含め、ファイルをコピーして変更日を設定するときにそれを読み取ります。これを変更して、作成日またはアクセス日を処理したり、いくつかの作業を組み合わせたりすることができます。

これがbashスクリプトです:(私はまだbashに慣れていないので、それを改善する方法についてのコメントは大歓迎です)

#!/bin/bash
#First parameter is the folder to recurse into, defaults to current directory
#Second parameter is the full path to a pList file without the extension, defaults to
#<CURRENT DIRECTORY>/fileInfo
#if you don't specify /'s in the parameter it will be treated as a domain instead and
#the pList will be elsewhere...

pinfoLoc=${2:-`pwd`/fileInfo}

#Useful for debugging
#echo Source: ${1:-.}
#echo Destination: $pinfoLoc

for i in ${1:-.}/*; do

  #Format: %Sa = last access, %Sm = last modified, %Sc = created
  date=`stat -f "%Sm" $i`

  #Uncomment below to see each file and date used
  #echo $i - $date

  #Write the data to the pList
  defaults write $pinfoLoc "$i" -date "$date" 

  #Recurse into directories, not sure if there's a better way to do this
  if [ -d "$i" ]; then
    bash $0 $i $pinfoLoc
  fi
done

基本的に、プロジェクトの外部に存在し、それにリンクされている「assets」というフォルダーがあり、XCode はそのフォルダーをバンドルにコピーします。バンドルからファイルをコピーした後に、各ファイルの変更日を更新するために思いついたコードを次に示します。

//Update file properties
NSString *file, *dstPath, *srcPath;
NSDictionary *fAttribs;
NSData *fInfoData = [fm contentsAtPath:[[NSBundle mainBundle] pathForResource:@"fileInfo" ofType:@"plist"]];
NSPropertyListFormat format;
NSDictionary *fileInfo = (NSDictionary *)[NSPropertyListSerialization
                                          propertyListWithData:fInfoData
                                          options:NSPropertyListMutableContainersAndLeaves
                                          format:&format
                                          error:&error];
NSString * resPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"assets"];
NSDirectoryEnumerator *dirEnum = [fm enumeratorAtPath:resPath];
while (file = [dirEnum nextObject])
{
    NSLog(@"Directory Enum File: %@", file);
    dstPath = [NSString pathWithComponents:@[[appInfo appSupportPath], @"res", file ]];
    srcPath = [@"assets" stringByAppendingPathComponent:file];
    fAttribs = @{ NSFileModificationDate: [fileInfo valueForKey:srcPath]};
    [fm setAttributes:fAttribs ofItemAtPath:dstPath error:&error];
    if (error)
    {
        NSLog(@"Error setting attribute to file: %@ - %@", file, error.localizedDescription);
        [error release];
        error = nil;
    }
}

これは私のファイルのコピー方法の後であり、見えない変数がいくつかあります。つまりfmは のデフォルト マネージャでNSFileManagerあり、errorは初期化されていないNSError[appInfo appSupportPath]あり、デバイス上のデータを保存するディレクトリを返す静的メソッドです (バンドルを変更できないため)。

また、日付を保持する plist の場所と、ファイルをコピーしたディレクトリをハードコーディングしました。後でコードで更新する予定です。

次に、スクリプトの実行を自動化し、fileInfo.plist も含めるように XCode をセットアップしました。後者は簡単です。スクリプトを実行したら、それを Xcode にドラッグ アンド ドロップして参照として保持できます。トリッキーな部分は、ビルドごとにスクリプトを実行することです。

  1. 上記の bash スクリプトをコピーしてファイルに貼り付けます
  2. Project Navigator でプロジェクトをクリックします。
  3. まだ選択されていない場合は、[ターゲット] でターゲット (アプリケーション名) を選択します。
  4. [ビルド フェーズ] タブをクリックします。
  5. 右下の [ビルド フェーズの追加] -> [実行スクリプトの追加] をクリックします。
  6. 新しいフェーズは最後になりますが、残念ながらそれは、生成しているファイルを含むファイルをバンドルにコピーした後です。そのため、フェーズを「バンドル リソースのコピー」のすぐ上にドラッグします。
  7. /bin/bash を入れたシェルの場合、/bin/sh も同様に機能する可能性があります...
  8. 以下の行にこれを入れます:

    pushd $PROJECT_DIR/..
    /PATH/TO/BASH/FILE/ABOVE.sh assets
    popd
    

    pushd $PROJECT_DIR/..アセット ディレクトリは私のプロジェクトの 1 レベル上にあるため、これが必要でした。代わりに移動するディレクトリをハードコーディングすることもでき、おそらくより明確になるでしょう。

  9. 今すぐビルドしようとすると、スクリプト ファイルに実行権限がないため、おそらく権限エラーが発生します。ターミナルを開いて実行するよりも、Macでこれを設定する簡単な方法を知りませんchmod +x <BASH FILE NAME>はい、誰もがそれを実行できることを理解しています. XCode が別のユーザーとしてビルドされているかどうか。

うまくいけば、これの少なくとも一部が役立ちます。この変更日を使用して、Web サーバーに新しいファイルがあるかどうかを確認し、必要なものだけをダウンロードします。

于 2012-12-18T23:27:41.117 に答える