Cocoa, Objective C MongoDB App using ObjCMongoDB.framework

Cocoa, Objective C MongoDB App using ObjCMongoDB.framework

Written by: Debasis Das (23-Jan-2015)

In this article we will create a simple Cocoa, Objective C App that connects to MongoDB Database through the ObjCMongoDB.framework

We will implement the following functionality in this project

  • Create an Employee Collection in a Database in MongoDB
  • Implement Find Functionality
  • Implement Add New Employee
  • Implement Modify Existing Employee & Save
  • Delete Employee Record

The signature of each employee record in the MongoDB Collection will be as follows

/*
 > db.employees.findOne()
 {
	"_id" : ObjectId("54347187dbbd79a1510148b3"),
	"employee_id" : "1000",
	"first_name" : "John",
	"last_name" : "Doe",
	"email" : "JohnDoe@knowstack.com",
	"phone_number" : "408-000-0000",
	"salary" : 713077,
	"year_exp" : 30,
	"designation" : "Senior Director",
	"department" : "Finance"
 }
 */

Find Screen Using Cocoa, Objective C, MongoDB, ObjCMongoDB.framework

Find Screen Using Cocoa, Objective C, MongoDB, ObjCMongoDB.framework

 

Add New Employee in Cocoa, Objective C, MongoDB, ObjCMongoDB.framework

Add New Employee in Cocoa, Objective C, MongoDB, ObjCMongoDB.framework

 

Modify Existing Employee Record in Cocoa, Objective C, MongoDB, ObjCMongoDB.framework

Modify Existing Employee Record in Cocoa, Objective C, MongoDB, ObjCMongoDB.framework

//
//  CocoaMongoWindowController.m
//  KSCocoaMongo
//
//  Created by Debasis Das on 1/22/15.
//  Copyright (c) 2015 Knowstack. All rights reserved.
//

#import "CocoaMongoWindowController.h"
extern NSString *const HOST_WITH_PORT;
extern NSString *const COLLECTION_NAME;
@class EmployeeWindowController;

@interface CocoaMongoWindowController ()
@property (nonatomic, assign) IBOutlet NSTableView *employeeTableView;
@property (nonatomic, assign) IBOutlet NSPopUpButton *designationPopupButton;
@property (nonatomic, assign) IBOutlet NSPopUpButton *salaryQueryPopupButton;
@property (nonatomic, assign) IBOutlet NSTextField *salaryTextField;
@end

@implementation CocoaMongoWindowController

//Following is the structure of data that will be displayed in this screen
/*
 > db.employees.findOne()
 {
	"_id" : ObjectId("54347187dbbd79a1510148b3"),
	"employee_id" : "1000",
	"first_name" : "John",
	"last_name" : "Doe",
	"email" : "JohnDoe@knowstack.com",
	"phone_number" : "408-000-0000",
	"salary" : 713077,
	"year_exp" : 30,
	"designation" : "Senior Director",
	"department" : "Finance"
 }
 */

NSString *const HOST_WITH_PORT = @"127.0.0.1";
NSString *const COLLECTION_NAME = @"knowstack.employees";

- (void)windowDidLoad {
    [super windowDidLoad];
    // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
}

-(NSString *)windowNibName
{
    return @"CocoaMongoWindow";
}


-(IBAction)find:(id)sender
{
    NSError *error = nil;
    MongoConnection *dbConn = [MongoConnection connectionForServer:HOST_WITH_PORT error:&error];
    MongoDBCollection *collection = [dbConn collectionWithName:COLLECTION_NAME];
    
    
    MongoKeyedPredicate *predicate = [MongoKeyedPredicate predicate];
    if ([self.salaryTextField intValue] !=0)
    {
        if ([[self.salaryQueryPopupButton titleOfSelectedItem] isEqualToString:@">"])
        {
            [predicate keyPath:@"salary" isGreaterThan:@([self.salaryTextField intValue])];
        }
        else if ([[self.salaryQueryPopupButton titleOfSelectedItem] isEqualToString:@"<"])
        {
            [predicate keyPath:@"salary" isLessThan:@([self.salaryTextField intValue])];
        }
        else if ([[self.salaryQueryPopupButton titleOfSelectedItem] isEqualToString:@"="])
        {
            [predicate keyPath:@"salary" matches:@([self.salaryTextField intValue])];
        }
    }
    
    NSArray *bSonArray = [collection findWithPredicate:predicate error:&error];
    NSMutableArray *mArray = [[NSMutableArray alloc] init];
    for (BSONDocument *doc in bSonArray)
    {
        [mArray addObject:[BSONDecoder decodeDictionaryWithDocument:doc]];
    }
    [self setDataArray:mArray];
    [mArray release];
    [self.employeeTableView reloadData];

}

-(IBAction)modify:(id)sender
{
    NSDictionary *employeeRecord = [self.dataArray objectAtIndex:[self.employeeTableView selectedRow]];
    [EmployeeWindowController initWithData:employeeRecord];
}

-(IBAction)delete:(id)sender
{
    NSError *error = nil;
    MongoConnection *dbConn = [MongoConnection connectionForServer:HOST_WITH_PORT error:&error];
    MongoDBCollection *collection = [dbConn collectionWithName:COLLECTION_NAME];
    MongoKeyedPredicate *predicate = [MongoKeyedPredicate predicate];
    
    
    [predicate keyPath:@"_id" matches:[[self.dataArray objectAtIndex:[self.employeeTableView selectedRow]] objectForKey:@"_id"]];
    [collection removeWithPredicate:predicate writeConcern:nil error:&error];
    [self find:self];
    if (error == NULL)
    {
        NSAlert *alert = [[NSAlert alloc] init];
        [alert setMessageText:@"Delete Confirmation"];
        [alert setInformativeText:@"The Employee has been deleted"];
        [alert runModal];
    }

}

-(IBAction)addEmployee:(id)sender
{
    EmployeeWindowController *ewc = [[EmployeeWindowController alloc] init];
    [ewc showWindow:self];
}

- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex
{
    NSString *aString;
    aString = [[self.dataArray objectAtIndex:rowIndex] objectForKey:[aTableColumn identifier]];
    return aString;
}

- (void)tableView:(NSTableView *)tableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
    [[self.dataArray objectAtIndex:row] setObject:object  forKey:[tableColumn identifier]];
}

- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
{
    long recordCount = [self.dataArray count];
    return recordCount;
}
@end
@interface EmployeeWindowController : NSWindowController
@property (assign) IBOutlet NSTextField *employeeIdTextField;
@property (assign) IBOutlet NSTextField *firstNameTextField;
@property (assign) IBOutlet NSTextField *lastNameTextField;
@property (assign) IBOutlet NSTextField *emailTextField;
@property (assign) IBOutlet NSTextField *phoneNumTextField;
@property (assign) IBOutlet NSTextField *salaryTextField;
@property (assign) IBOutlet NSTextField *yearExpTextField;
@property (assign) IBOutlet NSTextField *designationTextField;
@property (assign) IBOutlet NSTextField *departmentTextField;
@property (nonatomic, retain) NSDictionary *employeeDictionary;
@property (nonatomic, retain) NSString *recordId;

@end

@implementation EmployeeWindowController
@synthesize employeeIdTextField;

-(NSString *)windowNibName
{
    return @"EmployeeWindow";
}

+(void)initWithData:(NSDictionary *)employeeRecord
{
    EmployeeWindowController *obj = [[EmployeeWindowController alloc] init];
    [obj setEmployeeDictionary:employeeRecord];
    [obj showWindow:self];
}

-(void)awakeFromNib
{
    NSDictionary *emp = self.employeeDictionary;
    if (emp)
    {
        //Record Exists. This is a modify request
        [self.window setTitle:@"Modify Employee"];
        [self setRecordId:[emp objectForKey:@"_id"]];
        [self.employeeIdTextField setStringValue:[emp objectForKey:@"employee_id"]];
        [self.employeeIdTextField setEnabled:NO];
        [self.firstNameTextField setStringValue:[emp objectForKey:@"first_name"]];
        [self.lastNameTextField setStringValue:[emp objectForKey:@"last_name"]];
        [self.emailTextField setStringValue:[emp objectForKey:@"email"]];
        [self.phoneNumTextField setStringValue:[emp objectForKey:@"phone_number"]];
        [self.salaryTextField setStringValue:[emp objectForKey:@"salary"]];
        [self.yearExpTextField setStringValue:[emp objectForKey:@"year_exp"]];
        [self.designationTextField setStringValue:[emp objectForKey:@"designation"]];
        [self.departmentTextField setStringValue:[emp objectForKey:@"department"]];
    }
    else
    {
        //This is a new employee creation
        [self.window setTitle:@"Add New Employee"];
        NSLog(@"Do Nothing");
    }
}

-(IBAction)saveEmployee:(id)sender
{
    NSError *error = nil;
    MongoConnection *dbConn = [MongoConnection connectionForServer:HOST_WITH_PORT error:&error];
    MongoDBCollection *collection = [dbConn collectionWithName:COLLECTION_NAME];
    NSString *uniqueIdString = nil;
    
    if (self.recordId)
    {
        //Modify Request
        uniqueIdString = self.recordId;
    }
    else
    {
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        [dateFormatter setDateFormat:@"MMddyyyyhhmmss"];
        uniqueIdString = [dateFormatter stringFromDate:[NSDate date]];
    }


    NSDictionary *employeeRecord = [NSDictionary dictionaryWithObjectsAndKeys:
                                    uniqueIdString,@"_id",
                                    [self.employeeIdTextField stringValue],@"employee_id",
                                    [self.firstNameTextField stringValue],@"first_name",
                                    [self.lastNameTextField stringValue],@"last_name",
                                    [self.emailTextField stringValue],@"email",
                                    [self.phoneNumTextField stringValue],@"phone_number",
                                    [self.salaryTextField stringValue],@"salary",
                                    [self.yearExpTextField stringValue],@"year_exp",
                                    [self.designationTextField stringValue],@"designation",
                                    [self.departmentTextField stringValue],@"department",
                                    nil];
    if (self.recordId)
    {
        //Update Request
        MongoKeyedPredicate *predicate = [MongoKeyedPredicate predicate];
        [predicate keyPath:@"_id" matches:self.recordId];
        
        MongoUpdateRequest *updateRequest = [MongoUpdateRequest updateRequestWithPredicate:predicate firstMatchOnly:NO];
        [updateRequest keyPath:@"first_name" setValue:[self.firstNameTextField stringValue]];
        [updateRequest keyPath:@"last_name" setValue:[self.lastNameTextField stringValue]];
        [updateRequest keyPath:@"email" setValue:[self.emailTextField stringValue]];
        [updateRequest keyPath:@"phone_number" setValue:[self.phoneNumTextField stringValue]];
        [updateRequest keyPath:@"salary" setValue:[self.salaryTextField stringValue]];
        [updateRequest keyPath:@"year_exp" setValue:[self.yearExpTextField stringValue]];
        [updateRequest keyPath:@"designation" setValue:[self.designationTextField stringValue]];
        [updateRequest keyPath:@"department" setValue:[self.departmentTextField stringValue]];
        [collection updateWithRequest:updateRequest error:&error];
        if (error == NULL)
        {
            NSAlert *alert = [[NSAlert alloc] init];
            [alert setMessageText:@"Successfully Updated"];
            [alert setInformativeText:@"The Employee changes has been successfully updated"];
            [alert runModal];
        }

    }
    else
    {
        //Insert Request
        [collection insertDictionary:employeeRecord writeConcern:nil error:&error];
        if (error == NULL)
        {
            NSAlert *alert = [[NSAlert alloc] init];
            [alert setMessageText:@"New Employee Added"];
            [alert setInformativeText:@"The Employee has been added"];
            [alert runModal];
        }

    }
}
@end

You can download the source code from here
For further read on MongoDB
For further read on ObjCMongoDB


Posted in Cocoa, MongoDB, NoSQL, ObjCMongoDB.framework, Objective C Tagged with: , , , ,

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Recent Posts


Hit Counter provided by technology news