【问题标题】:iPhone read/write .plist fileiPhone 读/写 .plist 文件
【发布时间】:2012-03-09 06:42:10
【问题描述】:

我正在制作一个需要存储用户提供的信息的应用程序。我尝试使用 .plist 文件来存储信息,我发现了这个:

NSString *filePath = @"/Users/Denis/Documents/Xcode/iPhone/MLBB/data.plist";
NSMutableDictionary* plistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath];
[plistDict setValue:@"Man" forKey:@"Gender"];
[plistDict writeToFile:filePath atomically: YES];

问题是应用程序只有在我在 iPhone 模拟器中测试时才能工作。我试过这个Changing Data in a Plist 但没有运气。我还阅读了一些关于我需要将其添加到我的包中的内容,但是如何?

新代码:

- (IBAction)segmentControlChanged{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *plistLocation = [documentsDirectory stringByAppendingPathComponent:@"data.plist"];
NSMutableDictionary* plistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:plistLocation];

if (Gender.selectedSegmentIndex == 0) {
    [plistDict setObject:@"Man" forKey:@"Gender"];
    [plistDict writeToFile:plistLocation atomically: YES];
}
else
{
    [plistDict setObject:@"Women" forKey:@"Gender"];
    [plistDict writeToFile:plistLocation atomically: YES];
}
}

【问题讨论】:

    标签: iphone xcode plist


    【解决方案1】:

    我猜你已经将你的 plist 文件添加到 Xcode 中的资源文件夹中(我们放置图像的地方,如果没有,那么你需要先放置它)。资源数据默认转到[NSBundle mainBundle],iOS 不允许我们更改捆绑包中的数据。因此,首先您需要将该文件复制到 Documents Directory。

    这是将文件从NSBundle 复制到 Documents 目录的代码。

    - (NSString *)copyFileToDocumentDirectory:(NSString *)fileName {
        NSError *error;
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                                             NSUserDomainMask,
                                                             YES);
        NSString *documentsDir = [paths objectAtIndex:0];
        NSString *documentDirPath = [documentsDir
                                          stringByAppendingPathComponent:fileName];
    
        NSArray *file = [fileName componentsSeparatedByString:@"."];
        NSString *filePath = [[NSBundle mainBundle]
                                             pathForResource:[file objectAtIndex:0]
                                                      ofType:[file lastObject]];
    
        NSFileManager *fileManager = [NSFileManager defaultManager];
        BOOL success = [fileManager fileExistsAtPath:documentDirPath];
    
        if (!success) {
            success = [fileManager copyItemAtPath:filePath
                                           toPath:documentDirPath
                                            error:&error];
            if (!success) {
            NSAssert1(0, @"Failed to create writable txt file file with message \
                                             '%@'.", [error localizedDescription]);
            }
        }
    
        return documentDirPath;
    }
    

    现在您可以使用返回的documentDirPath 访问该文件并对其进行操作(读/写)。

    plist结构为:

    <array>
        <dict>key-value data</dict>
        <dict>key-value data</dict>
    </array>
    

    以下是将数据写入 plist 文件的代码:

    /* Code to write into file */
    
    - (void)addToMyPlist {
        // set file manager object
        NSFileManager *manager = [NSFileManager defaultManager];
    
        // check if file exists
        NSString *plistPath = [self copyFileToDocumentDirectory:
                                                           @"MyPlistFile.plist"];
    
        BOOL isExist = [manager fileExistsAtPath:plistPath];    
        // BOOL done = NO;
    
        if (!isExist) {
            // NSLog(@"MyPlistFile.plist does not exist");
            // done = [manager copyItemAtPath:file toPath:fileName error:&error];
        }
        // NSLog(@"done: %d",done);
    
        // get data from plist file
        NSMutableArray * plistArray = [[NSMutableArray alloc]
                                               initWithContentsOfFile:plistPath];
    
        // create dictionary using array data and bookmarkKeysArray keys
        NSArray *keysArray = [[NSArray alloc] initWithObjects:@"StudentNo", nil];
        NSArray *valuesArray = [[NSArray alloc] initWithObjects:
                                       [NSString stringWithFormat:@"1234"], nil];
    
        NSDictionary plistDict = [[NSDictionary alloc]
                                                      initWithObjects:valuesArray
                                                              forKeys:keysArray];
    
        [plistArray insertObject:poDict atIndex:0];
    
        // write data to  plist file
        //BOOL isWritten = [plistArray writeToFile:plistPath atomically:YES];
        [plistArray writeToFile:plistPath atomically:YES];
    
        plistArray = nil;
    
        // check for status
        // NSLog(@" \n  written == %d",isWritten);
    }
    

    【讨论】:

    • 我要如何处理这段代码?我试过只是粘贴它,但它没有用。我需要把文件名放在某个地方吗?
    • 资源文件夹在哪里?
    • 此代码用于获取 plist 文件的路径,即代码中的“plistLocation”。首先添加您的 plist 文件,以及您的图像。然后调用此方法获取 plist 文件路径,将其存储在您的“plistLocation”变量中,其余的代码就可以了
    • 那么在使用这段代码时我需要写什么而不是 plistLocation 呢?我需要对代码做什么,只需将其粘贴到我的 viewController.m 中?
    • 是的,在你的 viewController 中添加这个方法。调用此方法获取 plist 路径。 - (IBAction)segmentControlChanged{ NSArray paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; plistLocation = [self copyFileToDocumentDirectory:@"data.plist"]; NSMutableDictionary plistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:plistLocation]; [plistDict setValue:@"Man" forKey:@"Gender"]; [plistDict writeToFile:filePath atomically: YES];
    【解决方案2】:

    您是否在设备上使用相同的路径?设备上的应用程序是沙盒的,只能读取/写入其文档目录中的文件。获取该文件路径 like this 并附加您的 plist 名称。这种方法也适用于模拟器。

    试试这个:

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *plistLocation = [documentsDirectory stringByAppendingPathComponent:@"myplist.plist"];
    

    【讨论】:

    • 不,我没有尝试在“真实”设备上运行它,但我不希望它会运行,因为该目录在“真实”设备上不存在。我知道它们只能从自己的目录中读取/写入,但是我如何告诉 Xcode 使用应用程序目录中名为 data.plist 的文件而不是 /Users/Denis/Documents/Xcode/iPhone/MLBB/data。列表?我感觉像 n00b :-)
    • 我发布的那个链接向您展示了如何将文档目录作为字符串获取。使用 stringByAppendingString 在末尾添加您的 plist 名称,然后使用您指定的代码。就是这样:)
    • 对不起,我不明白你的意思。我写了 NSString *filePath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];但我不认为这就是你的意思。您能否编辑上面的代码以使其工作以及何时在此处编写。我是 Xcode 的新手,现在我知道成为 n00b 的感觉了 :-)
    • 我在上面添加了我当前的代码,但不明白为什么它不起作用。希望我有时能学会发现代码中的错误:-)
    • @DSDeniso Use setObject: forKey:, setValue: 用于不同的东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-05
    • 1970-01-01
    相关资源
    最近更新 更多