Register FAQ / Rules Forum Spy Search Today's Posts Mark Forums Read
Go Back   MacRumors Forums > Apple Systems and Services > Programming > iPhone/iPad Programming

Reply
 
Thread Tools Search this Thread Display Modes
Old Dec 12, 2012, 12:29 AM   #1
iphonedude2008
macrumors member
 
Join Date: Nov 2009
Problems saving files

I am trying to save files to the sandbox. I have an object with an array, which has many arrays, which in turn contains arrays that contain nsstrings, nsurls, uiimages, and other media objects. All the objects implement nscoding or nssecurecoding. It will archive the objects to nsdata and i can unarchive it right there, but i can not save it to the disk. What is going on and how can i get it to save to the disk. I prefer to use archives, but if i absolutely have to, i can use core data.

heres the code for the model
Code:
//
//  CQStorageModel.h
//  White Nova
//
//  Created by Mark Hill on 12/4/12.
//  Copyright (c) 2012 Mark Hill. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface CQStorageModel : NSObject<NSCoding>

@property (strong, nonatomic) NSMutableArray *dataSource;
@property (strong, nonatomic) NSURL *savingUrl;


//methods for saving and retreaving the datasource
- (id) initWithDataSource;
- (void) saveDataSource;
- (id) refreshData;


//methods for adding projects to the datasource
- (void) addProject: (NSMutableArray *) arry withName: (NSString *) string;
- (void) removeProjectAtIndex: (NSUInteger) index;
- (NSString *) loadProjectNameAtIndex: (NSUInteger) index;


//methods for adding objects to the datasource
- (void) addObject: (id<NSCoding>) object withName: (NSString *)name toProjectAtIndex: (NSUInteger) index;
- (void) removeObjectAtIndex: (NSUInteger) index1 inProjectAtIndex: (NSUInteger) index2;
- (id) loadObjectAtIndex: (NSUInteger) index1 inProjectAtIndex: (NSUInteger) index2;
- (NSString *) loadNameAtIndex: (NSUInteger) index1 inProjectAtIndex: (NSUInteger) index2;


//methods for giving counts
- (NSUInteger) projectCount;
- (NSUInteger) objectCountInProject: (NSUInteger) projectNumber;


//refreshers
- (void) changeNotify;

@end
Code:
//
//  CQStorageModel.m
//  White Nova
//
//  Created by Mark Hill on 12/4/12.
//  Copyright (c) 2012 Mark Hill. All rights reserved.
//

#import "CQStorageModel.h"

@implementation CQStorageModel

@synthesize dataSource;


//compling with nscoding to save and retreave this object
- (void) encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeObject:self.dataSource forKey:@"dataSource"];
    [aCoder encodeObject:self.savingUrl forKey:@"savingUrl"];
}

- (id) initWithCoder:(NSCoder *)aDecoder {
    self = [super init];
    self.dataSource = [aDecoder decodeObjectForKey:@"dataSource"];
    self.savingUrl = [aDecoder decodeObjectForKey:@"savingUrl"];
    return self;
}



//methods for saving and retreaving the datasource
- (id) initWithDataSource {
    self = [super init];
    if (self) {
        NSFileManager *fm = [[NSFileManager alloc]init];
        NSURL *appSupportUrl = [fm URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
        
        if (appSupportUrl == nil)
            appSupportUrl = [fm URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:nil];
        
        self.savingUrl = [appSupportUrl URLByAppendingPathComponent:@"CQStorageModel.cqstm"];
        [fm createDirectoryAtPath:self.savingUrl.path withIntermediateDirectories:YES attributes:nil error:nil];
        NSLog(@"%@", self.savingUrl.path);
        NSData *data = [[NSData alloc]initWithContentsOfURL:self.savingUrl];
        
        if (data)
        {
        self = [NSKeyedUnarchiver unarchiveObjectWithData:data];
        }
    
        self.dataSource = [NSMutableArray array];
        [self saveDataSource];
        NSLog(@"%@", self.savingUrl);
    }
    
    return self;
}

- (void) saveDataSource {
    BOOL ok = [NSKeyedArchiver archiveRootObject:self toFile:self.savingUrl.path];
    BOOL no = NO;
    //NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self];
    //[data writeToURL:self.savingUrl atomically:NO];
}

- (id) refreshData {
    id Data;
    NSFileManager *fm = [[NSFileManager alloc]init];
    NSURL *appSupportUrl = [fm URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
    
    if (!appSupportUrl)
        appSupportUrl = [fm URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:nil];
    
    self.savingUrl = [appSupportUrl URLByAppendingPathComponent:@"CQStorageModel.cqstm"];
    NSData *data = [[NSData alloc]initWithContentsOfURL:self.savingUrl];
    
    if (data)
    {
        Data = [NSKeyedUnarchiver unarchiveObjectWithData:data];
    }
    
    [self saveDataSource];
    return Data;
}




//methods for adding projects to the datasource
- (void) addProject: (NSMutableArray *) arry withName: (NSString *) string {
    [arry insertObject:string atIndex:0];
    [self.dataSource addObject:arry];
    [self saveDataSource];
    [self changeNotify];
}

- (void) removeProjectAtIndex:(NSUInteger)index {
    if (self.dataSource != nil) {
    [self.dataSource removeObjectAtIndex:index];
    [self saveDataSource];
    }
    [self changeNotify];
}


//methods for adding objects to the datasource
- (void) addObject:(id<NSCoding>)object withName:(NSString *)name toProjectAtIndex:(NSUInteger)index {
    NSMutableArray *marray = [NSMutableArray array];
    
    if (name.length == 0)
        [marray insertObject:[NSString stringWithFormat:@"file %i", [[self.dataSource objectAtIndex:index] count]] atIndex:0];
    else
        [marray insertObject:name atIndex:0];
    
    [marray insertObject:object atIndex:1];
    [[self.dataSource objectAtIndex:index] addObject:marray];
    [self saveDataSource];
    [self changeNotify];
}

- (void) removeObjectAtIndex:(NSUInteger)index1 inProjectAtIndex:(NSUInteger)index2 {
    if (index1 != 0)
        [[self.dataSource objectAtIndex:index2] removeObjectAtIndex:index1];
    [self saveDataSource];
    [self changeNotify];
}

- (id) loadObjectAtIndex:(NSUInteger)index1 inProjectAtIndex:(NSUInteger)index2 {
    if (self.dataSource != nil) {
    id object = [[[self.dataSource objectAtIndex:index2] objectAtIndex:(index1 + 1)] objectAtIndex:1];
    return object;
    }
    else
        return nil;
}



//methods for getting names
- (NSString *) loadNameAtIndex:(NSUInteger)index1 inProjectAtIndex:(NSUInteger)index2 {
    if (self.dataSource != nil) {
            NSString *string = [[[self.dataSource objectAtIndex:index2] objectAtIndex:(index1 + 1)]objectAtIndex:0];
            return string;
    }
        return nil;
}

- (NSString *) loadProjectNameAtIndex:(NSUInteger)index {
    if (self.dataSource != nil && [self.dataSource count] > (index)) {
        NSString *strg = [[self.dataSource objectAtIndex:index] objectAtIndex:0];
        return strg;
    }
    else return @"";
}


//methods for giving counts

- (NSUInteger) projectCount {
    if (self.dataSource != nil) 
    return [self.dataSource count];
    else
        return 0;
}

- (NSUInteger) objectCountInProject:(NSUInteger)projectNumber {
    if (self.dataSource != nil && [self.dataSource count] != 0) {
        if ([self.dataSource objectAtIndex:projectNumber] != nil) {
            return ([[self.dataSource objectAtIndex:projectNumber] count] - 1);
        }
        }
        return 0;
}




//refresher

- (void) changeNotify {
    [[NSNotificationCenter defaultCenter]postNotificationName:@"data changed" object:self];
}


@end

Last edited by iphonedude2008; Dec 12, 2012 at 10:51 AM.
iphonedude2008 is offline   0 Reply With Quote
Old Dec 12, 2012, 04:06 AM   #2
robbieduncan
Moderator
 
robbieduncan's Avatar
 
Join Date: Jul 2002
Location: London
What is the value of savingURL?
robbieduncan is offline   0 Reply With Quote
Old Dec 12, 2012, 09:39 AM   #3
iphonedude2008
Thread Starter
macrumors member
 
Join Date: Nov 2009
A file in the app support directory
iphonedude2008 is offline   0 Reply With Quote
Old Dec 12, 2012, 09:52 AM   #4
robbieduncan
Moderator
 
robbieduncan's Avatar
 
Join Date: Jul 2002
Location: London
Quote:
Originally Posted by iphonedude2008 View Post
Code:
//methods for saving and retreaving the datasource
- (id) initWithDataSource {
    self = [super init];
    if (self) {
        NSFileManager *fm = [[NSFileManager alloc]init];
        NSURL *appSupportUrl = [fm URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
        
        if (appSupportUrl == nil)
            appSupportUrl = [fm URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:nil];
        
        self.savingUrl = [appSupportUrl URLByAppendingPathComponent:@"CQStorageModel.cqstm"];
        [fm createDirectoryAtPath:self.savingUrl.path withIntermediateDirectories:YES attributes:nil error:nil];
- (void) saveDataSource {
    BOOL ok = [NSKeyedArchiver archiveRootObject:self toFile:self.savingUrl.path];
    BOOL no = NO;
    NSLog(@"%i", no);
    NSLog(@"hi %i", ok);
    //NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self];
    //[data writeToURL:self.savingUrl atomically:NO];
}

This looks sketchy to say the least. You set the savingURL. Then you create a directory at that path. That means you now have a directory called "CQStorageModel.cqstm" within the application support directory. This will prevent you writing a file with the same name...
robbieduncan is offline   0 Reply With Quote
Old Dec 12, 2012, 10:47 AM   #5
iphonedude2008
Thread Starter
macrumors member
 
Join Date: Nov 2009
How should I fix it then? I don't quite understand what you said. I was trying to make a file inside the app support directory to save my model object to. Is that what I am doing and is there a better way?
iphonedude2008 is offline   0 Reply With Quote
Old Dec 12, 2012, 11:32 AM   #6
robbieduncan
Moderator
 
robbieduncan's Avatar
 
Join Date: Jul 2002
Location: London
Quote:
Originally Posted by iphonedude2008 View Post
How should I fix it then? I don't quite understand what you said. I was trying to make a file inside the app support directory to save my model object to. Is that what I am doing and is there a better way?
Break the following lines down, one at a time, explaining for each what you think it is doing (the lines numbered like (1)). Include where appropriate what the paths are, the log output and the expected change in the file system. You should see where the issue is (or you have not understood what the documentation says each method does):

Quote:
Originally Posted by iphonedude2008 View Post
Code:
//methods for saving and retreaving the datasource
- (id) initWithDataSource {
    self = [super init];
    if (self) {
        NSFileManager *fm = [[NSFileManager alloc]init];
(1)        NSURL *appSupportUrl = [fm URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
        
        if (appSupportUrl == nil)
(2)            appSupportUrl = [fm URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:nil];
        
(3)        self.savingUrl = [appSupportUrl URLByAppendingPathComponent:@"CQStorageModel.cqstm"];
(4)        [fm createDirectoryAtPath:self.savingUrl.path withIntermediateDirectories:YES attributes:nil error:nil];

...

- (void) saveDataSource {
(5)    BOOL ok = [NSKeyedArchiver archiveRootObject:self toFile:self.savingUrl.path];
(6)    BOOL no = NO;
(7)    NSLog(@"%i", no);
(8)    NSLog(@"hi %i", ok);
    //NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self];
    //[data writeToURL:self.savingUrl atomically:NO];
}
robbieduncan is offline   0 Reply With Quote
Old Dec 12, 2012, 04:34 PM   #7
iphonedude2008
Thread Starter
macrumors member
 
Join Date: Nov 2009
I figured out it is a problem with this line in saveDataSource.

Code:
- (void) saveDataSource {
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self];
    NSError *err = nil;
    [data writeToFile:self.savingUrl.path options:NSDataWritingAtomic error:&err];
    NSLog(@"%@", [err localizedDescription]);
}
it prints out this

The operation couldnít be completed. (Cocoa error 512.)
iphonedude2008 is offline   0 Reply With Quote
Old Dec 12, 2012, 05:14 PM   #8
robbieduncan
Moderator
 
robbieduncan's Avatar
 
Join Date: Jul 2002
Location: London
Quote:
Originally Posted by iphonedude2008 View Post
I figured out it is a problem with this line in saveDataSource.

Code:
- (void) saveDataSource {
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self];
    NSError *err = nil;
    [data writeToFile:self.savingUrl.path options:NSDataWritingAtomic error:&err];
    NSLog(@"%@", [err localizedDescription]);
}
it prints out this

The operation couldnít be completed. (Cocoa error 512.)
No, the error is where I've 1) told you and 2) guided you to work you for your self. This is just a symptom of the earlier error. If you worked through the lines I suggested you would see the issue.
robbieduncan is offline   0 Reply With Quote

Reply
MacRumors Forums > Apple Systems and Services > Programming > iPhone/iPad Programming

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -5. The time now is 01:30 AM.

Mac Rumors | Mac | iPhone | iPhone Game Reviews | iPhone Apps

Mobile Version | Fixed | Fluid | Fluid HD
Copyright 2002-2013, MacRumors.com, LLC