2011-08-20 29 views
0

道歉的含糊不清的問題標題...是否有可能通過NSBundles共享圖像?

這裏是我的方案:

我動態地從筆尖存儲在NSBundles文件

BOOL bundlePathExists = [fm fileExistsAtPath:bundlePath]; 
if (bundlePathExists) { 
    NSBundle *tempBundle = [NSBundle bundleWithPath:bundlePath]; 

    UIViewController *vc = [[UIViewController alloc] initWithNibName:nibName bundle:tempBundle]; 

    [self.view addSubview:vc.view]; 
} 

(注加載UIView的內容:上面是一個簡化了實際代碼的摘錄,因爲不會混淆問題的性質 - 做這件事的機制相對有據可查here

這些nib文件包含一個數字的圖像,其中一些對於該包是獨一無二的,還有一些是在多個包之間共享的。

我希望能夠存儲主包中常見的圖像,因此它們不會佔用其他包中的空間,並最大限度地減少整個項目的維護 - 例如,如果我改變了那些常見的圖像之一,我寧願不必重建它引用的每一個束。

我知道我可以編程方式做到這一點通過使用

[commonImageViewIvar setImage:[UIImage imageWithName:commonImageName]]; 

但是我更願意實現這一目標而無需編寫自定義代碼爲每個視圖(即實例化的視圖控制器不是按筆尖定製的,因此所有的信息需求存儲在筆尖)

+0

它出現我可以使用設備上的文件夾文件夾中的符號鏈接(例如,通過鏈接myApp.app/Documents/instance.bundle/commonImage.png - > myApp.app/commonImage.png)來完成我所需要的操作。我將很快發佈我的通用解決方案。 – unsynchronized

+0

編輯原始問題以正確鏈接(請參閱上面相對良好的「此處」) - 對試圖遵循該鏈接的任何人致歉。 – unsynchronized

回答

0

如這裏承諾是我想出了一個解決方案:

束文件本身所描述的here下載。要添加這裏列出的信息,我發現如果您先在iPhone應用程序中創建視圖,則可以在模擬器中預覽它們。然後,可以創建一個新項目作爲捆綁包,然後將所有圖像文件& xib & .h文件拖放到新項目中。不要拖動.m文件,因爲這會造成構建問題。那麼請確保項目設置將BASE SDK定義爲「最新的IOS」,而不是將要選擇的默認Mac OS X設置。然後你可以通過雙擊來編輯xib。通過取消選擇該文件的「目標」列,可以從構建中取消選擇任何公用文件。請參閱本答覆文章後面的「其他信息」。

有一次我在從服務器zip文件下載的每捆,我使用下面的方法我編寫用於此目的:

-(NSArray *) imageFileExtensions { 
    return [NSArray arrayWithObjects:@".png",@".gif",@".jpg",@".jpeg",@".bmp", nil]; 
} 

-(void) cloneImageFilesInPath:(NSString *)path toPath:(NSString*)clonePath { 

    NSFileManager *fm = [NSFileManager defaultManager]; 
    NSArray *extensions = [self imageFileExtensions]; 
    if ([fm fileExistsAtPath:path]) { 
     NSArray *files = [fm contentsOfDirectoryAtPath:path error:nil]; 

     for (NSString *file in files){ 
      for (NSString *ext in extensions) { 
       if ([file hasSuffix:ext]) { 
        NSString *targetFile = [clonePath stringByAppendingPathComponent:file]; 
        if (![fm fileExistsAtPath:targetFile]) { 
         [fm createSymbolicLinkAtPath:targetFile withDestinationPath:[path stringByAppendingPathComponent:file] error:nil]; 
        } 
        break; 
       } 
      } 

     } 
    } 

} 

這些方法創建掃描主應用程序包目錄中,並且對於不在定製包目錄中的每個圖像文件,將在定製包目錄內創建一個符號鏈接以指向主應用程序包目錄。

他們在我的應用程序委託調用如下:

 ...(insert code to unzip the file to bundlePath here)... 

     [self cloneImageFilesInPath:[[NSBundle mainBundle] bundlePath] toPath:bundlePath]; 

信息

創建實際的包,我犯了一個單獨的應用程序,從自定義包目錄中刪除所有圖像文件,如果這些文件名存在於包含部署在主應用程序包中的公用圖像文件的目錄中。我後來發現,您可以通過取消選擇該文件的目標列複選框來阻止xcode從構建中包含某些文件,因此不一定需要執行此步驟 - 但如果您有大量的創建視圖,則可能更容易離開他們在捆綁中,並使用這種方法去除它們。

-(void) removeDuplicatedImageFilesInPath:(NSString *)sourcePath fromTargetPath:(NSString*)path { 

    NSFileManager *fm = [NSFileManager defaultManager]; 
    NSArray *extensions = [self imageFileExtensions]; 
    if ([fm fileExistsAtPath:path]) { 
     NSArray *files = [fm contentsOfDirectoryAtPath:sourcePath error:nil]; 

     for (NSString *file in files){ 
      for (NSString *ext in extensions) { 
       if ([file hasSuffix:ext]) { 
        NSString *targetPath = [path stringByAppendingPathComponent:file]; 
        if ([fm fileExistsAtPath:targetPath]) { 
         [fm removeItemAtPath:targetPath error:nil]; 
        } 
        break; 
       } 
      } 

     } 
    } 

} 

用於處理壓縮文件

更多信息,我選擇使用ObjectiveZip(以下通過海報here的建議。爲了簡化任務,我裹着這在以下2個應用程序的委託方法(一個是在實際應用中使用,另一個在脫機包創建應用程序)

在主應用

-(void) unzipArchive:(NSString *)zipFileName toPath:(NSString *)path { 
    NSFileManager *fm = [NSFileManager defaultManager]; 

    ZipFile *unzipFile = [[ZipFile alloc] initWithFileName:zipFileName mode:ZipFileModeUnzip]; 

    NSArray *infos= [unzipFile listFileInZipInfos]; 

    [unzipFile goToFirstFileInZip]; 
    for (FileInZipInfo *info in infos) { 

     ZipReadStream *read1= [unzipFile readCurrentFileInZip]; 

     NSMutableData *fileData = [[[NSMutableData alloc] initWithLength:info.length] autorelease]; 
     int bytesRead1 = [read1 readDataWithBuffer:fileData]; 

     if (bytesRead1 == info.length) { 
      NSString *fileName = [path stringByAppendingPathComponent:info.name ]; 
      NSString *filePath = [fileName stringByDeletingLastPathComponent]; 

      [fm createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:nil]; 


      [fileData writeToFile:fileName atomically:YES]; 

     } 

     [read1 finishedReading];   

     [unzipFile goToNextFileInZip]; 

    } 

    [unzipFile close]; 
    [unzipFile release]; 


} 

和自定義捆綁包創建離線應用程序。

-(void) createArchive:(NSString *) zipFileName usingPath:(NSString *)path { 
    NSArray *files = [self filesInDirectory:path]; 
    ZipFile *zipFile= [[ZipFile alloc] initWithFileName:zipFileName mode:ZipFileModeCreate]; 

    for (NSString *file in files) { 

     NSString *fileNameForZip = [file substringFromIndex:path.length]; 

     ZipWriteStream *stream= [zipFile writeFileInZipWithName:fileNameForZip fileDate:[NSDate dateWithTimeIntervalSinceNow:-86400.0] compressionLevel:ZipCompressionLevelBest]; 

     [stream writeData:[NSData dataWithContentsOfFile:file]]; 

     [stream finishedWriting]; 
    } 
    [zipFile close]; 
    [zipFile release]; 
} 

注:先前的方法依賴於以下2種方法,其創建一個包含在給定路徑中的所有文件的完全合格的路徑一個NSArray(遞歸到子目錄)

-(void)loadFilesInDirectory:(NSString *)path intoArray:(NSMutableArray *)files { 
    NSFileManager *fm = [NSFileManager defaultManager]; 

    NSMutableArray *fileList = [NSMutableArray arrayWithArray:[fm contentsOfDirectoryAtPath:path error:nil]]; 
    for (NSString *file in fileList) { 
     BOOL isDirectory = NO; 
     NSString *filePath = [path stringByAppendingPathComponent:file]; 
     if ([fm fileExistsAtPath:filePath isDirectory:&isDirectory]) { 
      if (isDirectory) { 
       [self loadFilesInDirectory:filePath intoArray:files]; 
      } else { 
       [files addObject:filePath]; 
      };   

     }; 
    } 
} 


-(NSArray *)filesInDirectory:(NSString *)path { 
    NSMutableArray *files = [NSMutableArray array]; 
    [self loadFilesInDirectory:path intoArray:files]; 
    return files; 
} 
相關問題