2012年11月24日 星期六

總結目錄與檔案讀寫的功能

總結一下目錄與檔案讀寫。選項很多,暫時整理資料如下


目錄操作可參考  http://kusodir.blogspot.tw/2011/10/objective-c.html


NSFileManager 用於檔案操作的方法:
方法說明
-(BOOL) createFileAtPath: (NSString *) path content: (NSData *) contents attributes: (NSDictionary *) attributes建立具有 contents 的內容,以及 attributes 屬性的檔案。若建立成功則回傳 YES,否則回傳 NO
-(NSDictionary *) attributesOfItemAtPath: (NSString *) path error: (NSError **) error回傳 path 指定的檔案或目錄屬性,若過程有發生任何錯誤,則將錯誤訊息記錄於 error 物件
-(BOOL) removeItemAtPath: (NSString *) path error: (NSError **) error若成功刪除 path 指定的檔案、連結、目錄,則回傳 YES,否則將錯誤訊息記錄於 error 物件,並回傳 NO。(此方法將刪除所有子目錄中的內容)
-(BOOL) moveItemAtPath: (NSString *) srcPath toPath: (NSString *) dstPath error: (NSError **) error將 srcPath 的檔案或目錄移至 dstPath,若移動成功,則回傳 YES,否則回傳 NO。(只有最後一層名稱不同的話,代表更改名稱)
-(BOOL) fileExistsAtPath: (NSString *) path若 path 指定的檔案存在,則回傳 YES,否則回傳 NO



NSFileManager 用於目錄操作的方法:
方法說明
-(BOOL) createDirectoryAtPath: (NSString *) path attributes: (NSDictionary *) attributes error: (NSError **) error建立 path 指定的目錄,且此目錄具有 attributes 的屬性。若成功建立目錄,則回傳 YES,否則回傳 NO
-(BOOL) changeCurrentDirectoryPath: (NSString *) path改變目前的目錄為 path
-(NSString *) currentDirectoryPath回傳目前程式所在之路徑
-(NSDirectoryEnumerator *) enumeratorAtPath: (NSString *) path回傳 path 指定路徑的內容,內容包含檔案與目錄
-(BOOL)fileExistsAtPath (NSString *) path若 path 指定的檔案存在,則回傳 YES,否則回傳 NO




NSString 路徑操作方法:
函式說明
NSString * NSFullUserName (void)回傳目前使用者的完整名稱
NSString * NSHomeDirectory (void)回傳目前使用者家目錄的路徑
NSString * NSHomeDirectoryForUser (NSString* userName)回傳使用者 userName 家目錄的路徑
NSString * NSTemporaryDirectory (void)回傳目前使用者暫存目錄的路徑
方法說明
+(NSString *) pathWithComponents: (NSArray *) components以 components 陣列為初始數值,初始為檔案路徑格式
-(NSArray *) pathComponents回傳依字串路徑切分的字串陣列
-(NSString *) lastPathComponent取得字串路徑最後一個檔案或目錄名稱
-(NSString *) pathExtension取得字串路徑的延伸檔名
-(NSString *) stringByAppendingPathComponent: (NSString *) aString在字串尾端附加檔案或目錄名稱
-(NSString *) stringByAppendingPathExtension: (NSString *) ext在字串尾端附加檔案的延伸檔名
-(NSString *) stringByDeletingLastPathComponent刪除字串路徑最後一個檔案或目錄的名稱
-(NSString *) stringByDeletingPathExtension刪除字串路徑的延伸檔名
-(NSString *) stringByExpandingTildeInPath將字串路徑中的 ~ (目前使用者家目錄) 與 ~user (指定使用者家目錄) 展開為完整路徑
-(NSString *) stringByStandardizingPath將字串路徑標準化,展開 ~ 、 ~user,去除 //、 ./ 、 / 、..


基本使用例可參考
http://www.techotopia.com/index.php/Working_with_Files_on_iOS_4_%28Xcode_4%29


basic example

//取得可讀寫的路徑
NSArray *pathList = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [pathList  objectAtIndex:0];
 
//加上檔名
path = [path stringByAppendingPathComponent:filename];
NSLog([@"存取檔案的路徑:" stringByAppendingString: path]);
 
//寫入檔案
NSString *data = @"file data";
[data writeToFile:path atomically:NO encoding:NSUTF8StringEncoding error:nil];
 
 
 // 取得新建檔案的屬性
 NSDictionary* attr = [fmanager attributesOfItemAtPath:path error:NULL];
 NSLog(@"新建檔案的屬性 :");
 for(NSString* tempAttr in attr){
  NSLog(@"%@ - %@",tempAttr,[attr objectForKey: tempAttr]);
 }
 
//讀取檔案
NSString *rdata = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
NSLog([@"檔案內容:" stringByAppendingString: rdata]);
 
//判斷檔案是否存在
if([[NSFileManager defaultManager] fileExistsAtPath:path]) {
     NSLog([@"檔案存在,開始刪除:" stringByAppendingString: path]);
     //刪除檔案
     [[NSFileManager defaultManager] removeItemAtPath:path error:nil];
}


對於檔案的屬性,操作上需要瞭解及注意
官方文件參考如下
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/nsfilemanager_Class/Reference/Reference.html#//apple_ref/doc/constant_group/File_Attribute_Keys

使用範例
// Get the size of newfile2
if ((attr = [fm fileAttributesAtPath: @ ” newfile2 ” traverseLink: NO]) == nil) {
   NSLog (@ ” Couldn ’ t get file attributes! ” );
   return 5;
}
NSLog (@ ” File size is %i bytes ” , [[attr objectForKey: NSFileSize] intValue]);


屬性變數  (objectForKey: xxx)

NSFileAppendOnly
NSNumber... boolean
NSFileCreationDate
NSDate when the file was created (if supported)
NSFileDeviceIdentifier
NSNumber (identifies the device on which the file is stored)
NSFileExtensionHidden
NSNumber... boolean
NSFileGroupOwnerAccountName
NSString name of the file group
NSFileGroupOwnerAccountID
NSNumber ID of the file group
NSFileHFSCreatorCode
NSNumber not used
NSFileHFSTypeCode
NSNumber not used
NSFileImmutable
NSNumber... boolean
NSFileModificationDate
NSDate when the file was last modified
NSFileOwnerAccountName
NSString name of the file owner
NSFileOwnerAccountID
NSNumber ID of the file owner
NSFilePosixPermissions
NSNumber posix access permissions mask
NSFileReferenceCount
NSNumber number of links to this file
NSFileSize
NSNumber size of the file in bytes
NSFileSystemFileNumber
NSNumber the identifier for the file on the filesystem
NSFileSystemNumber
NSNumber the filesystem on which the file is stored
NSFileType
NSString the type of file 






2012年11月23日 星期五

iOS上的目錄(四)

在整個IOS的目錄中,除了App本身的局部目錄外,還有其他系統方面,或是資料下載的暫存,等等的各種目錄。此處要透過 NSSearchPathDirectory 這個enum來定義,然後找出所對應的目錄。

以下是實作方法,因為只針對目錄,因此次目錄以下的檔案就不處理。

1. 此處開啓一個全新的測試專案

2. 在StoryBoard加上textView/Label/Button/Pickview



3. 在mainViewController.h註冊所需元件
#import <UIKit/UIKit.h>

@interface mainViewController : UIViewController

@property (weak, nonatomic)  NSFileManager *fileManager;
@property (weak, nonatomic)  NSString *targetDirectory;
@property (weak, nonatomic)  NSString *filePath;

@property (weak, nonatomic) IBOutlet UITextView *textView;

@property (nonatomic) NSMutableArray *arrayDirectory;

@property (weak, nonatomic) IBOutlet UILabel *arrayDirectoryLabel;

@property (weak, nonatomic) IBOutlet UIPickerView *pickView;


@end

4. 在mainViewController.m加上所需程式碼
#import "mainViewController.h"

@interface mainViewController ()

@end

@implementation mainViewController

@synthesize fileManager, filePath;
@synthesize targetDirectory;

@synthesize textView;

@synthesize pickView;

@synthesize arrayDirectory;

@synthesize arrayDirectoryLabel;

int rowValue = 0;

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
   
    arrayDirectory = [[NSMutableArray alloc] init];
    [arrayDirectory addObject:@"NSApplicationDirectory"];
    [arrayDirectory addObject:@"NSDemoApplicationDirectory"];
    [arrayDirectory addObject:@"NSDeveloperApplicationDirectory"];
    [arrayDirectory addObject:@"NSAdminApplicationDirectory"];
    [arrayDirectory addObject:@"NSLibraryDirectory"];
    [arrayDirectory addObject:@"NSDeveloperDirectory"];
    [arrayDirectory addObject:@"NSUserDirectory"];
    [arrayDirectory addObject:@"NSDocumentationDirectory"];
    [arrayDirectory addObject:@"NSDocumentDirectory"];
    [arrayDirectory addObject:@"NSCoreServiceDirectory"];
    [arrayDirectory addObject:@"NSAutosavedInformationDirectory"];
    [arrayDirectory addObject:@"NSDesktopDirectory"];
    [arrayDirectory addObject:@"NSCachesDirectory"];
    [arrayDirectory addObject:@"NSApplicationSupportDirectory"];
    [arrayDirectory addObject:@"NSDownloadsDirectory"];
    [arrayDirectory addObject:@"NSInputMethodsDirectory"];
    [arrayDirectory addObject:@"NSMoviesDirectory"];
    [arrayDirectory addObject:@"NSMusicDirectory"];
    [arrayDirectory addObject:@"NSPicturesDirectory"];
    [arrayDirectory addObject:@"NSPrinterDescriptionDirectory"];
    [arrayDirectory addObject:@"NSSharedPublicDirectory"];
    [arrayDirectory addObject:@"NSPreferencePanesDirectory"];
    [arrayDirectory addObject:@"NSApplicationScriptsDirectory"];
    [arrayDirectory addObject:@"NSItemReplacementDirectory"];
    [arrayDirectory addObject:@"NSAllApplicationsDirectory"];
    [arrayDirectory addObject:@"NSAllLibrariesDirectory"];
    [arrayDirectory addObject:@"NSTrashDirectory"];

      
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
- (IBAction)listDirectory:(id)sender {
   
    textView.text = [textView.text stringByAppendingFormat:@"Home at %@ \n",NSHomeDirectory()];
   
    fileManager = [NSFileManager defaultManager];//利用類別方法取得檔案系統的一個預設NSFileManager實體
   
    NSArray *filelist;
   
    filelist = NSSearchPathForDirectoriesInDomains(rowValue, NSAllDomainsMask, YES);
     
    int i=0;
   
    BOOL flag;
   
    int count = [filelist count];
   
    //依序列出資料夾下的資料有哪些
    for (i = 0; i < count; i++) {
        

textView.text = [textView.text stringByAppendingFormat:@"%d, %@ \n",i,[filelist objectAtIndex: i]];
       
    }

}

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)thePickerView {
   
    return 1;
}

- (NSInteger)pickerView:(UIPickerView *)thePickerView numberOfRowsInComponent:(NSInteger)component {
   
    return [arrayDirectory count];
}

- (NSString *)pickerView:(UIPickerView *)thePickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
   
    return [arrayDirectory objectAtIndex:row];
}

- (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
   
    arrayDirectoryLabel.text = [NSString stringWithFormat:@"%@",[arrayDirectory objectAtIndex:row]];
   
    if (row<=23)  //這邊的值要參考原始enum的設定

       rowValue = row +1;
    else {
       rowValue = row +99;
    }
   
}
- (IBAction)clearDisplay:(id)sender {
   
    textView.text = @" ";
   
}


@end

5. 結果顯示



2012年11月22日 星期四

iOS上的目錄(三)

因為在IOS目錄中有儲存文件的Document,另外有暫存的tmp目錄。現在要在兩個目錄中增加及刪除檔案,因此實作上做了大幅修改,以便可以靈活的測試,增減檔案的功能。

1. 在StoryBoard中,增加Button/Switch/TextField


2. mainViewController.h

#import <UIKit/UIKit.h>

@interface mainViewController : UIViewController

@property (weak, nonatomic) IBOutlet UITextView *textView;
@property (weak, nonatomic) IBOutlet UISwitch *overwriteSwitch;
@property (weak, nonatomic) IBOutlet UISwitch *tmpSwitch;
@property (weak, nonatomic) IBOutlet UISwitch *subDirectoryDisplay;
@property (weak, nonatomic) IBOutlet UITextField *filenameInput;

@property (weak, nonatomic)  NSFileManager *fileManager;
@property (weak, nonatomic)  NSString *targetDirectory;
@property (weak, nonatomic)  NSString *filePath;


@end


3. 在mainViewController.m增加程式碼
#import "mainViewController.h"

@interface mainViewController ()

@end

@implementation mainViewController

@synthesize textView;
@synthesize overwriteSwitch;
@synthesize tmpSwitch;
@synthesize subDirectoryDisplay;
@synthesize filenameInput;

@synthesize fileManager;
@synthesize targetDirectory;
@synthesize filePath;


- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)PressedButton:(id)sender {
    

    textView.text = [textView.text stringByAppendingFormat:@"%@ \n",NSHomeDirectory()];
   
    NSFileManager *file = [NSFileManager defaultManager];//利用類別方法取得檔案系統的一個預設NSFileManager實體
    //利用這個,可以對根目錄裡的檔案進行操作。
    NSDirectoryEnumerator *dir = [file enumeratorAtPath:NSHomeDirectory()];
    NSString *currPath;
   
    int i=0;
   
    BOOL flag;
    //依序列出資料夾下的資料有哪些
    while (currPath = [dir nextObject]) {
       
        //NSLog(@"%d, Found : %@", i,currPath);
        textView.text = [textView.text stringByAppendingFormat:@"%d, %@ \n",i,currPath];
       
        i++;
       
        if (subDirectoryDisplay.on == 0)
        {
            [file fileExistsAtPath:currPath isDirectory: &flag];
           
            if (flag == YES)
                [dir skipDescendants];
        }
    }
}

- (IBAction)copyFile:(id)sender {
   
    fileManager = [NSFileManager defaultManager];
    NSError *error;
   
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
   
    if (tmpSwitch.on == 1)
        targetDirectory = NSTemporaryDirectory();
    else
        targetDirectory = [paths objectAtIndex:0];
   
    filePath = [targetDirectory stringByAppendingPathComponent:filenameInput.text];
   
    if (overwriteSwitch.on == 1)
    {
        if ([fileManager fileExistsAtPath:filePath] == YES) {
            [fileManager removeItemAtPath:filePath error:&error];
           
        }
    }
   
    if ([fileManager fileExistsAtPath:filePath] == NO) {
        NSString *resourcePath = [[NSBundle mainBundle] pathForResource:@"test1" ofType:@"txt"];
        [fileManager copyItemAtPath:resourcePath toPath:filePath error:&error];
    }
}

- (IBAction)ReadFile:(id)sender {
   
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
   
    NSString *filePath = [documentsDirectory stringByAppendingPathComponent:filenameInput.text];
   
    if (filePath) {
       
        NSString *contentOfFile = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
       
        textView.text = contentOfFile;
       
    }

}
- (IBAction)deleteFile:(id)sender {

    fileManager = [NSFileManager defaultManager];
   
    NSError *error;
   
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
   
       
    if (tmpSwitch.on == 1)
        targetDirectory = NSTemporaryDirectory();
    else
        targetDirectory = [paths objectAtIndex:0];
   
    filePath= [targetDirectory stringByAppendingPathComponent:filenameInput.text];
   
    if ([fileManager fileExistsAtPath:filePath] == YES) {
        [fileManager removeItemAtPath:filePath error:&error];
       
        textView.text = [textView.text stringByAppendingFormat:@"remove file ==> %@ \n",filePath];
   
    }
}
- (IBAction)clearDisplayArea:(id)sender {
   
    textView.text = @" ";
}


@end



4. 執行結果,可以瞭解到,檔案可以分別儲存到Document及tmp這兩個目錄,並且也可以使用中文檔名。


2012年11月21日 星期三

iOS上的目錄(二)

試著在iOS上寫入檔案,因此放一個測試檔在Resource,然後copy檔案到Document的目錄

實作

1. 延續前一篇的專案,在StoryBoard加上兩個Button及一個textView,來做試驗,其中IOS Directory的前身為Button

2. 加入一個測試檔


3.先將檔案copy到document目錄,將test1.txt拷貝到Document,並改名為textFile1.txt
- (IBAction)copyFile:(id)sender {
   
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0]; // document目錄
   
    NSLog(@"documentsDirectory ==> %@",documentsDirectory);
   
    NSString *txtPath = [documentsDirectory stringByAppendingPathComponent:@"txtFile1.txt"];
   
    NSLog(@"path ==> %@",txtPath);

  
    if ([fileManager fileExistsAtPath:txtPath] == NO) {
        NSString *resourcePath = [[NSBundle mainBundle] pathForResource:@"test1" ofType:@"txt"];
        [fileManager copyItemAtPath:resourcePath toPath:txtPath error:&error];
    }
}


4. 做完上面的測試,先用IOS Directory這個Button來列印IOS的目錄,來驗證是否拷貝成功。因為有txtFile.txt及txtFile1.txt,其原因是做兩次拷貝,分別完成了兩個檔案。

0, Found : Documents
2012-11-21 22:27:56.117 myDirectoryOperation[11464:c07] 1, Found : Documents/txtFile.txt
2012-11-21 22:27:56.117 myDirectoryOperation[11464:c07] 2, Found : Documents/txtFile1.txt
2012-11-21 22:27:56.117 myDirectoryOperation[11464:c07] 3, Found : Library
2012-11-21 22:27:56.118 myDirectoryOperation[11464:c07] 4, Found : Library/Caches

5. 增加程式碼到ReadFile Button,來讀取拷貝的檔案,並顯示到TextView
- (IBAction)ReadFile:(id)sender {
   
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
   
    NSLog(@"documentsDirectory ==> %@",documentsDirectory);
   
    NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"txtFile1.txt"];
   
    NSLog(@"path ==> %@",filePath);
       
    if (filePath) {
        //NSString *contentOfFile = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
       
        NSString *contentOfFile = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
       
        textView.text = contentOfFile;
       
    }
}


6. 測試結果

2012年11月20日 星期二

iOS上的目錄(ㄧ)

要在IOS上操作檔案的讀寫,就必須瞭解整個IOS上有什麼目錄,以下是整理的資料

 1. 在Xcode上的StoryBoard開啓一個Button,然後在此Button上的IBAction加上以下的程式碼,來印出IOS上的目錄



    NSLog(@"%@",NSHomeDirectory());//取得目前以此app名稱為根目錄的資料夾位置
   
    NSFileManager *file = [NSFileManager defaultManager];//利用類別方法取得檔案系統的一個預設NSFileManager實體
    //利用這個,可以對根目錄裡的檔案進行操作。
    NSDirectoryEnumerator *dir = [file enumeratorAtPath:NSHomeDirectory()];
    NSString *currPath;
    //依序列出資料夾下的資料有哪些
    while (currPath = [dir nextObject]) {
        NSLog(@"Found : %@",currPath);
    }


2.印出的目錄如下,紅色部分為程式可讀取的根目錄下的次目錄。
2012-11-20 22:16:18.191 myDirectoryOperation[6427:c07] /Users/UserName/Library/Application Support/iPhone Simulator/6.0/Applications/DAACFF36-EB0B-4A71-9417-C92DFEC37228
2012-11-20 22:16:18.193 myDirectoryOperation[6427:c07] Found : Documents
2012-11-20 22:16:18.194 myDirectoryOperation[6427:c07] Found : Library
2012-11-20 22:16:18.194 myDirectoryOperation[6427:c07] Found : Library/Caches
2012-11-20 22:16:18.194 myDirectoryOperation[6427:c07] Found : Library/Preferences
2012-11-20 22:16:18.195 myDirectoryOperation[6427:c07] Found : Library/Preferences/.GlobalPreferences.plist
2012-11-20 22:16:18.195 myDirectoryOperation[6427:c07] Found : Library/Preferences/com.apple.PeoplePicker.plist
2012-11-20 22:16:18.196 myDirectoryOperation[6427:c07] Found : myDirectoryOperation.app
2012-11-20 22:16:18.196 myDirectoryOperation[6427:c07] Found : myDirectoryOperation.app/Default-568h@2x.png
2012-11-20 22:16:18.196 myDirectoryOperation[6427:c07] Found : myDirectoryOperation.app/Default.png
2012-11-20 22:16:18.197 myDirectoryOperation[6427:c07] Found : myDirectoryOperation.app/Default@2x.png
2012-11-20 22:16:18.197 myDirectoryOperation[6427:c07] Found : myDirectoryOperation.app/en.lproj
2012-11-20 22:16:18.197 myDirectoryOperation[6427:c07] Found : myDirectoryOperation.app/en.lproj/InfoPlist.strings
2012-11-20 22:16:18.200 myDirectoryOperation[6427:c07] Found : myDirectoryOperation.app/en.lproj/MainStoryboard.storyboardc
2012-11-20 22:16:18.200 myDirectoryOperation[6427:c07] Found : myDirectoryOperation.app/en.lproj/MainStoryboard.storyboardc/2-view-5.nib
2012-11-20 22:16:18.201 myDirectoryOperation[6427:c07] Found : myDirectoryOperation.app/en.lproj/MainStoryboard.storyboardc/Info.plist
2012-11-20 22:16:18.201 myDirectoryOperation[6427:c07] Found : myDirectoryOperation.app/en.lproj/MainStoryboard.storyboardc/UIViewController-2.nib
2012-11-20 22:16:18.201 myDirectoryOperation[6427:c07] Found : myDirectoryOperation.app/Info.plist
2012-11-20 22:16:18.202 myDirectoryOperation[6427:c07] Found : myDirectoryOperation.app/myDirectoryOperation
2012-11-20 22:16:18.202 myDirectoryOperation[6427:c07] Found : myDirectoryOperation.app/PkgInfo
2012-11-20 22:16:18.202 myDirectoryOperation[6427:c07] Found : tmp

參考官方文件上的圖片
官方文件
http://developer.apple.com/library/ios/#documentation/FileManagement/Conceptual/FileSystemProgrammingGUide/FileSystemOverview/FileSystemOverview.html


The local OS X file system


 還有其它的主目錄,並沒有全部印出來,但是官方文件有說明,因此就不貼出了。


在存取目錄下的檔案有下列三種Function可資利用

//專案中的靜態檔案
NSString *path = [[NSBundle mainBundle] pathForResource:@"檔名" ofType:@"副檔名"];
 
//應用程式的家目錄
NSString *path = NSHomeDirectory();
 
//應用程式的暫存區
NSString *path = NSTemporaryDirectory();

2012年11月19日 星期一

IOS App上架經驗分享(二)

因為第二次上架的時候,發現有些生疏,以至於延遲了上架的時間。在此做些筆記,以便未來有參考的依據。


1. 要先在Developer上加新的Profile,作為app的驗證碼,這樣後續的上架才有可能進行。除了Distribution之外,Development也要做。這樣開發及上傳驗證碼才完整。




2. 可以先看看有沒有加進到帳號的驗證碼,如果需要就下載並更新到keychain。




3. 完成後並下載,就會看到有以下檔案,包含要上傳的app,點擊最上面兩個,來安裝app的驗證碼。


4. 在Xcode上應該要看到app的驗證碼,如果沒看到,可能需要將Xcode重新關閉再開啓。(如藍色打勾的部分)

5. 大概就這些要特別注意,當然App的ID也要注意申請。

2012年11月18日 星期日

Popover在iPad上的使用(二)

繼承前一篇的做法,Popover使用Button去做Dismiss的動作

在iPad的實作上,Popover是經常使用的一個顯示方式,而要回到主視窗時,除了使用手勢點及主視窗外,應該也要支援Button回去的方法,以下是實作的方法。

 資料參考
http://www.colejoplin.com/2012/09/12/ios-tutorial-combining-delegation-storyboards-popovers-and-data/

實作步驟

1. 開啓一個專案


2. 在sotryboard加入一個新的UIViewController,並在兩個UIViewController,個別加上一個Button及一個TextField

3. 加入新的UIViewController的class檔案,命名為popoverViewControlller

4.對Segue命名為segPop

5. 因為要用Delegate,所以要先從popoverViewController.h開始
#import <UIKit/UIKit.h>

@protocol PopViewControllerDelegate;    // Declare a protocol name

@interface popoverViewController : UIViewController

// Declare a property for the delegate
@property (weak) id <PopViewControllerDelegate> delegate;

// Declare a properly where a delegate can send data to this class
@property (strong, nonatomic) NSString *strPassedValue;

@property (weak, nonatomic) IBOutlet UITextField *popoverTextField;
@property (weak, nonatomic) IBOutlet UIButton *popoverButton;


@end

// Protocol Header
@protocol PopViewControllerDelegate <NSObject>
@required
- (void)dismissPop:(NSString *)value;


@end

6. 針對popoverViewController.m的內容作coding
#import "popoverViewController.h"

@implementation popoverViewController

@synthesize popoverButton,popoverTextField;

// getter/setter for header properties
@synthesize delegate;
@synthesize strPassedValue;



- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (void)viewWillAppear:(BOOL)animated {


    // 把主視窗傳來的值顯示出來
    [popoverTextField setText:strPassedValue];
}

- (IBAction)goBack:(id)sender {
    

    // 把值傳回主視窗,呼叫主視窗的dismissPop
    [delegate dismissPop:[popoverTextField text]];  // make delegate callback here
}


@end

7. 把delegate的變數套到mainViewControlller.h
#import <UIKit/UIKit.h>
#import "popoverViewController.h"   // add header to gain access to its protocol

@interface mainViewController : UIViewController  <PopViewControllerDelegate, UIPopoverControllerDelegate>

@property (weak, nonatomic) IBOutlet UIButton *popBautton;
@property (weak, nonatomic) IBOutlet UITextField *mainTextField;

// Properties for accessing the popover and its viewcontroller
@property (strong, nonatomic) UIStoryboardPopoverSegue *currentPopoverSegue;
@property (strong, nonatomic) popoverViewController *pvc;


@end

8. 設定
#import "mainViewController.h"

@interface mainViewController ()

@end

@implementation mainViewController

@synthesize popBautton;
@synthesize mainTextField;

// getter/setter for popover properties
@synthesize currentPopoverSegue;
@synthesize pvc;


- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

//啟動popover視窗
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
   
    if ([[segue identifier] isEqualToString:@"segPop"]) {
        currentPopoverSegue = (UIStoryboardPopoverSegue *)segue;
        pvc = [segue destinationViewController];  //設定popover
        [pvc setDelegate:self];






       
      
//將值傳送到popover視窗,透過setStrPassedValue這個內定Function傳送NSString
       [pvc setStrPassedValue:[mainTextField text]]; 
     }
}


// PopViewControllerDelegate callback function
- (void)dismissPop:(NSString *)value {
    [mainTextField setText:value]; // populates data from popover





    // dismiss the popover
    [[currentPopoverSegue popoverController] dismissPopoverAnimated: YES];
}



@end

9.執行結果,兩個UIView可互相傳遞字串