Archive for August, 2013

iOS and OS X: Utility class for accessing NSManagedObjectModel and NSManagedObjectContext

Some projects templates by XCode wizards provide code for accessing NSManagedObjectModel and NSManagedObjectContext, but some other do not. In case of projects which were not provided with auto-generated code for accessing model data, here is a class (based on these auto-genereted stuff) which accesses NSManagedObjectModel and NSManagedObjectContext. For the code to work properly, values for field “objectModelFileName” and “bundleIndentifier” have to be provided. For example, if name of file with model data is “MyApp.xcdatamodelId”, then “objectModelFileName” should have value “MyApp” and “bundleIndentifier” should have value which is equal to name of the application’s bundle name.

Header:

#import <Cocoa/Cocoa.h>

@interface ManagedObjectContextProvider : NSObject

@property (retain, nonatomic) NSString *objectModelFileName;
@property (retain, nonatomic) NSString *bundleIndentifier;

@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;

@end

Class definition:

#import "ManagedObjectContextProvider.h"

@implementation ManagedObjectContextProvider

@synthesize objectModelFileName = __objectModelFileName;
@synthesize bundleIndentifier = __bundleIndentifier;

@synthesize persistentStoreCoordinator = __persistentStoreCoordinator;
@synthesize managedObjectModel = __managedObjectModel;
@synthesize managedObjectContext = __managedObjectContext;

// Returns the directory the application uses to store the Core Data store file. 
- (NSURL *)applicationFilesDirectory
{
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSURL *appSupportURL = [[fileManager URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask] lastObject];
    return [appSupportURL URLByAppendingPathComponent:__bundleIndentifier];
}

// Creates if necessary and returns the managed object model for the application.
- (NSManagedObjectModel *)managedObjectModel
{
    if (__managedObjectModel) {
        return __managedObjectModel;
    }
	
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:__objectModelFileName withExtension:@"momd"];
    __managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    return __managedObjectModel;
}

// Returns the persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it. (The directory for the store is created, if necessary.)
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (__persistentStoreCoordinator) {
        return __persistentStoreCoordinator;
    }
    
    NSManagedObjectModel *mom = [self managedObjectModel];
    if (!mom) {
        NSLog(@"%@:%@ No model to generate a store from", [self class], NSStringFromSelector(_cmd));
        return nil;
    }
    
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSURL *applicationFilesDirectory = [self applicationFilesDirectory];
    NSError *error = nil;
    
    NSDictionary *properties = [applicationFilesDirectory resourceValuesForKeys:[NSArray arrayWithObject:NSURLIsDirectoryKey] error:&error];
    
    if (!properties) {
        BOOL ok = NO;
        if ([error code] == NSFileReadNoSuchFileError) {
            ok = [fileManager createDirectoryAtPath:[applicationFilesDirectory path] withIntermediateDirectories:YES attributes:nil error:&error];
        }
        if (!ok) {
            [[NSApplication sharedApplication] presentError:error];
            return nil;
        }
    } else {
        if (![[properties objectForKey:NSURLIsDirectoryKey] boolValue]) {
            // Customize and localize this error.
            NSString *failureDescription = [NSString stringWithFormat:@"Expected a folder to store application data, found a file (%@).", [applicationFilesDirectory path]];
            
            NSMutableDictionary *dict = [NSMutableDictionary dictionary];
            [dict setValue:failureDescription forKey:NSLocalizedDescriptionKey];
            error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:101 userInfo:dict];
            
            [[NSApplication sharedApplication] presentError:error];
            return nil;
        }
    }
    
    NSURL *url = [applicationFilesDirectory URLByAppendingPathComponent:@"CocoaApp1.storedata"];
    NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];
    if (![coordinator addPersistentStoreWithType:NSXMLStoreType configuration:nil URL:url options:nil error:&error]) {
        [[NSApplication sharedApplication] presentError:error];
        return nil;
    }
    __persistentStoreCoordinator = coordinator;
    
    return __persistentStoreCoordinator;
}

// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
- (NSManagedObjectContext *)managedObjectContext
{
    if (__managedObjectContext) {
        return __managedObjectContext;
    }
    
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (!coordinator) {
        NSMutableDictionary *dict = [NSMutableDictionary dictionary];
        [dict setValue:@"Failed to initialize the store" forKey:NSLocalizedDescriptionKey];
        [dict setValue:@"There was an error building up the data file." forKey:NSLocalizedFailureReasonErrorKey];
        NSError *error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
        [[NSApplication sharedApplication] presentError:error];
        return nil;
    }
    __managedObjectContext = [[NSManagedObjectContext alloc] init];
    [__managedObjectContext setPersistentStoreCoordinator:coordinator];
    
    return __managedObjectContext;
}


@end

Leave a comment

Simple configuration file for a .NET application

In order to read simple “key-value” configuration file for a .NET application, a class shown below may be used:


using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace SomeNamespace
{
    public class SimpleConfigurationManager
    {
        public static string GetConfigurationParameterValue(string key)
        {
            Configuration config = ConfigurationManager.OpenExeConfiguration(Assembly.GetExecutingAssembly().Location);
            try
            {
                AppSettingsSection c = (AppSettingsSection)config.GetSection("some_section_in_config_file");
                var i = c.ElementInformation;
                return c.Settings[key].Value;
            }
            catch (Exception e)
            {
                return null;
            }
        }
    }
}

The config file, which will be read by the class:

  1. should be stored in the same directory as the executable file
  2. should be named according to this pattern: executable file name + “.config”, for example: MyApp.exe.config
  3. should have following structure:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="some_section_in_config_file" type="System.Configuration.AppSettingsSection" />
  </configSections>

  <some_section_in_config_file>
    <add key="some_key_1" value="1024" />
    <add key="some_key_2" value="www.google.com" />
    <add key="and_some_other_key" value="true" />
  </some_section_in_config_file>

</configuration>

Leave a comment