Browse files

Initial commit

  • Loading branch information...
0 parents commit 89b3e750c3aaf28965315649eee2795e1da74223 @snej snej committed Aug 18, 2011
10 .gitignore
@@ -0,0 +1,10 @@
+.DS_Store
+*.swp
+*.pbxuser
+*.perspectivev3
+*.mode1v3
+xcuserdata/
+build/
+Documentation/
+Frameworks/
+
39 Classes/Event.h
@@ -0,0 +1,39 @@
+
+/*
+ File: Event.h
+ Abstract: A class to represent an event containing geographical coordinates, a time stamp, and an image with a thumbnail. Every Event has a CouchDB document.
+
+ Version: 1.1
+ */
+
+#import <CoreLocation/CoreLocation.h>
+@class CouchDatabase, CouchDocument;
+
+@interface Event : NSObject {
+ CouchDocument* document;
+ UIImage* photo;
+ UIImage* thumbnail;
+ BOOL checkedForPhoto;
+}
+
+/** Creates a brand-new event and adds a document for it to the database. */
+- (id)initWithDatabase:(CouchDatabase*)database
+ latitude:(CLLocationDegrees)latitude
+ longitude:(CLLocationDegrees)longitude
+ creationDate:(NSDate*)creationDate;
+
+/** Instantiates an Event object for an already-existing document. */
+- (id)initWithDocument:(CouchDocument*)document;
+
+/** Deletes the event's document from the database permanently. */
+- (void) deleteDocument;
+
+@property (nonatomic, readonly) NSDate *creationDate;
+@property (nonatomic, readonly) NSNumber* latitude;
+@property (nonatomic, readonly) NSNumber* longitude;
+
+@property (nonatomic, retain) UIImage *photo;
+@property (nonatomic, readonly) UIImage *thumbnail;
+
+@end
+
166 Classes/Event.m
@@ -0,0 +1,166 @@
+
+/*
+ File: Event.m
+ Abstract: A class to represent an event containing geographical coordinates, a time stamp, and an image with a thumbnail. Every Event has a CouchDB document.
+
+ Version: 1.1
+ */
+
+#import "Event.h"
+
+#import <CouchCocoa/CouchCocoa.h>
+#import <CouchCocoa/RESTBody.h>
+
+
+static UIImage* MakeThumbnail(UIImage* image, CGFloat dimensions);
+
+
+@implementation Event
+
+
+- (id)initWithDatabase:(CouchDatabase*)database
+ latitude:(CLLocationDegrees)latitude
+ longitude:(CLLocationDegrees)longitude
+ creationDate:(NSDate*)creationDate {
+ self = [super init];
+ if (self) {
+ NSDictionary* properties = [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithDouble: latitude], @"latitude",
+ [NSNumber numberWithDouble: longitude], @"longitude",
+ [RESTBody JSONObjectWithDate: creationDate], @"creationDate",
+ nil];
+ document = [[database untitledDocument] retain];
+ RESTOperation* op = [document putProperties: properties];
+ if (![op wait]) {
+ // TODO: report error
+ NSLog(@"Creating Event document failed! %@", op.error);
+ }
+ }
+ return self;
+}
+
+
+- (id)initWithDocument:(CouchDocument*)aDocument {
+ self = [super init];
+ if (self) {
+ document = [aDocument retain];
+ }
+ return self;
+}
+
+
+- (void)dealloc {
+ [document release];
+ [thumbnail release];
+ [super dealloc];
+}
+
+
+- (void) deleteDocument {
+ [[document DELETE] start];
+ [document release];
+ document = nil;
+}
+
+
+- (NSDate*) creationDate {
+ NSString* dateString = [document.properties objectForKey: @"creationDate"];
+ return [RESTBody dateWithJSONObject: dateString];
+}
+
+
+- (NSNumber*) latitude {
+ return [document.properties objectForKey: @"latitude"];
+}
+
+
+- (NSNumber*) longitude {
+ return [document.properties objectForKey: @"longitude"];
+}
+
+
+- (UIImage*)thumbnail {
+ // The thumbnail is stored inline as Base64-encoded data, because it's small.
+ if (!thumbnail) {
+ NSString* thumbnailBase64 = [document.properties objectForKey: @"thumbnail"];
+ NSData* thumbnailData = [RESTBody dataWithBase64: thumbnailBase64];
+ if (thumbnailData) {
+ thumbnail = [[UIImage alloc] initWithData: thumbnailData];
+ }
+ }
+ return thumbnail;
+}
+
+
+- (UIImage*)photo {
+ // The photo is stored as an attachment, so it is fetched separately on demand.
+ if (!checkedForPhoto) {
+ checkedForPhoto = YES;
+ CouchAttachment* attach = [document.currentRevision attachmentNamed: @"photo"];
+ RESTOperation* op = [attach GET];
+ if ([op isSuccessful]) {
+ NSData* imageData = op.responseBody.content;
+ photo = [[UIImage alloc] initWithData: imageData];
+ }
+ }
+ return photo;
+}
+
+
+- (void)setPhoto:(UIImage *)newPhoto {
+ if (checkedForPhoto && newPhoto == photo)
+ return;
+ [photo release];
+ photo = [newPhoto retain];
+ checkedForPhoto = YES;
+
+ // Update the thumbnail image:
+ [thumbnail release];
+ thumbnail = nil;
+ NSData* thumbnailData = nil;
+ if (newPhoto) {
+ thumbnail = [MakeThumbnail(newPhoto, 44) retain];
+ thumbnailData = UIImageJPEGRepresentation(thumbnail, 0.5);
+ }
+
+ // Save the thumbnail inline:
+ NSMutableDictionary* properties = [[document.properties mutableCopy] autorelease];
+ [properties setValue:[RESTBody base64WithData:thumbnailData] forKey:@"thumbnail"];
+ RESTOperation* op = [document putProperties:properties];
+ if (![op wait]) {
+ // TODO: Report error
+ NSLog(@"Saving Event document failed! %@", op.error);
+ }
+
+ // Save the photo to an attachment, asynchronously:
+ CouchAttachment* attach = [document.currentRevision createAttachmentWithName:@"photo"
+ type:@"image/png"];
+ if (newPhoto) {
+ op = [attach PUT: UIImagePNGRepresentation(newPhoto) contentType: @"image/png"];
+ } else {
+ op = [attach DELETE];
+ }
+ [op onCompletion: ^{
+ if (!op.isSuccessful) {
+ // TODO: Report error
+ NSLog(@"Saving Event photo attachment failed! %@", op.error);
+ }
+ }];
+}
+
+
+@end
+
+
+/** Makes a shrunk-down copy of an image. */
+static UIImage* MakeThumbnail(UIImage* image, CGFloat dimensions) {
+ CGSize size = image.size;
+ CGFloat ratio = dimensions / MAX(size.height, size.width);
+ CGRect rect = CGRectMake(0.0, 0.0, ratio * size.width, ratio * size.height);
+
+ UIGraphicsBeginImageContext(rect.size);
+ [image drawInRect:rect];
+ UIImage* thumbnail = UIGraphicsGetImageFromCurrentImageContext();
+ UIGraphicsEndImageContext();
+ return thumbnail;
+}
30 Classes/EventDetailViewController.h
@@ -0,0 +1,30 @@
+
+/*
+ File: EventDetailViewController.h
+ Abstract: The table view controller responsible for displaying the time, coordinates, and photo of an event, and allowing the user to select a photo for the event, or delete the existing photo.
+
+ Version: 1.1
+ */
+
+@class Event;
+
+@interface EventDetailViewController : UIViewController <UINavigationControllerDelegate, UIImagePickerControllerDelegate> {
+ Event *event;
+ UILabel *timeLabel;
+ UILabel *coordinatesLabel;
+ UIButton *deletePhotoButton;
+ UIImageView *photoImageView;
+}
+
+@property (nonatomic, retain) Event *event;
+
+@property (nonatomic, retain) IBOutlet UILabel *timeLabel;
+@property (nonatomic, retain) IBOutlet UILabel *coordinatesLabel;
+@property (nonatomic, retain) IBOutlet UIButton *deletePhotoButton;
+@property (nonatomic, retain) IBOutlet UIImageView *photoImageView;
+
+- (IBAction)choosePhoto;
+- (IBAction)deletePhoto;
+- (void)updatePhotoInfo;
+
+@end
127 Classes/EventDetailViewController.m
@@ -0,0 +1,127 @@
+
+/*
+ File: EventDetailViewController.m
+ Abstract: The table view controller responsible for displaying the time, coordinates, and photo of an event, and allowing the user to select a photo for the event, or delete the existing photo.
+
+ Version: 1.1
+ */
+
+#import "EventDetailViewController.h"
+#import "Event.h"
+
+
+@implementation EventDetailViewController
+
+@synthesize event, timeLabel, coordinatesLabel, deletePhotoButton, photoImageView;
+
+
+#pragma mark -
+#pragma mark Lifecycle
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ // A date formatter for the creation date.
+ static NSDateFormatter *dateFormatter = nil;
+ if (dateFormatter == nil) {
+ dateFormatter = [[NSDateFormatter alloc] init];
+ [dateFormatter setTimeStyle:NSDateFormatterShortStyle];
+ [dateFormatter setDateStyle:NSDateFormatterMediumStyle];
+ }
+
+ static NSNumberFormatter *numberFormatter;
+ if (numberFormatter == nil) {
+ numberFormatter = [[NSNumberFormatter alloc] init];
+ [numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
+ [numberFormatter setMaximumFractionDigits:3];
+ }
+
+ timeLabel.text = [dateFormatter stringFromDate:[event creationDate]];
+
+ NSString *coordinatesString = [[NSString alloc] initWithFormat:@"%@, %@",
+ [numberFormatter stringFromNumber:[event latitude]],
+ [numberFormatter stringFromNumber:[event longitude]]];
+ coordinatesLabel.text = coordinatesString;
+ [coordinatesString release];
+
+ [self updatePhotoInfo];
+}
+
+
+- (void)viewDidUnload {
+
+ self.timeLabel = nil;
+ self.coordinatesLabel = nil;
+ self.deletePhotoButton = nil;
+ self.photoImageView = nil;
+}
+
+
+#pragma mark -
+#pragma mark Editing the photo
+
+- (IBAction)deletePhoto {
+ [event setPhoto:nil];
+
+ // Update the user interface appropriately.
+ [self updatePhotoInfo];
+}
+
+
+- (IBAction)choosePhoto {
+
+ // Show an image picker to allow the user to choose a new photo.
+
+ UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
+ imagePicker.delegate = self;
+ [self presentModalViewController:imagePicker animated:YES];
+ [imagePicker release];
+}
+
+
+
+- (void)updatePhotoInfo {
+
+ // Synchronize the photo image view and the text on the photo button with the event's photo.
+ UIImage *image = event.photo;
+
+ photoImageView.image = image;
+ deletePhotoButton.enabled = (image != nil);
+}
+
+
+#pragma mark -
+#pragma mark Image picker delegate methods
+
+- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)selectedImage editingInfo:(NSDictionary *)editingInfo {
+ // Update the database.
+ event.photo = selectedImage;
+ // Update the user interface appropriately.
+ [self updatePhotoInfo];
+
+ [self dismissModalViewControllerAnimated:YES];
+}
+
+
+- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
+ // The user canceled -- simply dismiss the image picker.
+ [self dismissModalViewControllerAnimated:YES];
+}
+
+
+#pragma mark -
+#pragma mark Memory management
+
+- (void)dealloc {
+
+ [event release];
+ [timeLabel release];
+ [coordinatesLabel release];
+ [deletePhotoButton release];
+ [photoImageView release];
+
+ [super dealloc];
+}
+
+
+@end
478 Classes/EventDetailViewController.xib
@@ -0,0 +1,478 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.10">
+ <data>
+ <int key="IBDocument.SystemTarget">768</int>
+ <string key="IBDocument.SystemVersion">11A511</string>
+ <string key="IBDocument.InterfaceBuilderVersion">1900</string>
+ <string key="IBDocument.AppKitVersion">1138</string>
+ <string key="IBDocument.HIToolboxVersion">566.00</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="NS.object.0">894</string>
+ </object>
+ <object class="NSArray" key="IBDocument.IntegratedClassDependencies">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>IBUIButton</string>
+ <string>IBUIImageView</string>
+ <string>IBUIView</string>
+ <string>IBUILabel</string>
+ <string>IBProxyObject</string>
+ </object>
+ <object class="NSArray" key="IBDocument.PluginDependencies">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <string key="NS.key.0">PluginDependencyRecalculationVersion</string>
+ <integer value="1" key="NS.object.0"/>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBProxyObject" id="372490531">
+ <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBProxyObject" id="975951072">
+ <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBUIView" id="191373211">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">292</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBUIImageView" id="916784208">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">274</int>
+ <string key="NSFrame">{{0, 75}, {320, 276}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="1072420158"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+ <int key="IBUIContentMode">1</int>
+ <bool key="IBUIUserInteractionEnabled">NO</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBUIButton" id="145267981">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">292</int>
+ <string key="NSFrame">{{173, 359}, {127, 37}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <int key="IBUIContentHorizontalAlignment">0</int>
+ <int key="IBUIContentVerticalAlignment">0</int>
+ <int key="IBUIButtonType">1</int>
+ <string key="IBUINormalTitle">Choose Photo</string>
+ <object class="NSColor" key="IBUIHighlightedTitleColor" id="241564824">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ </object>
+ <object class="NSColor" key="IBUINormalTitleColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA</bytes>
+ </object>
+ <object class="NSColor" key="IBUINormalTitleShadowColor" id="769178084">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MC41AA</bytes>
+ </object>
+ <object class="IBUIFontDescription" key="IBUIFontDescription" id="120367086">
+ <string key="name">Helvetica-Bold</string>
+ <string key="family">Helvetica</string>
+ <int key="traits">2</int>
+ <double key="pointSize">15</double>
+ </object>
+ <object class="NSFont" key="IBUIFont" id="124139957">
+ <string key="NSName">Helvetica-Bold</string>
+ <double key="NSSize">15</double>
+ <int key="NSfFlags">16</int>
+ </object>
+ </object>
+ <object class="IBUIButton" id="1072420158">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">292</int>
+ <string key="NSFrame">{{20, 359}, {127, 37}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="145267981"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <int key="IBUIContentHorizontalAlignment">0</int>
+ <int key="IBUIContentVerticalAlignment">0</int>
+ <int key="IBUIButtonType">1</int>
+ <string key="IBUINormalTitle">Delete Photo</string>
+ <reference key="IBUIHighlightedTitleColor" ref="241564824"/>
+ <object class="NSColor" key="IBUINormalTitleColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA</bytes>
+ </object>
+ <reference key="IBUINormalTitleShadowColor" ref="769178084"/>
+ <reference key="IBUIFontDescription" ref="120367086"/>
+ <reference key="IBUIFont" ref="124139957"/>
+ </object>
+ <object class="IBUILabel" id="510191587">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">292</int>
+ <string key="NSFrame">{{20, 49}, {280, 18}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="916784208"/>
+ <reference key="IBUIBackgroundColor" ref="241564824"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <bool key="IBUIUserInteractionEnabled">NO</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <string key="IBUIText">Coordinates</string>
+ <object class="NSColor" key="IBUITextColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes>
+ </object>
+ <nil key="IBUIHighlightedColor"/>
+ <int key="IBUIBaselineAdjustment">1</int>
+ <float key="IBUIMinimumFontSize">10</float>
+ <int key="IBUITextAlignment">1</int>
+ <object class="IBUIFontDescription" key="IBUIFontDescription">
+ <string key="name">Helvetica</string>
+ <string key="family">Helvetica</string>
+ <int key="traits">0</int>
+ <double key="pointSize">14</double>
+ </object>
+ <object class="NSFont" key="IBUIFont">
+ <string key="NSName">Helvetica</string>
+ <double key="NSSize">14</double>
+ <int key="NSfFlags">16</int>
+ </object>
+ </object>
+ <object class="IBUILabel" id="840199335">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">292</int>
+ <string key="NSFrame">{{20, 20}, {280, 21}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="510191587"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <bool key="IBUIUserInteractionEnabled">NO</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <string key="IBUIText">Time</string>
+ <object class="NSColor" key="IBUITextColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MCAwIDAAA</bytes>
+ </object>
+ <nil key="IBUIHighlightedColor"/>
+ <int key="IBUIBaselineAdjustment">1</int>
+ <float key="IBUIMinimumFontSize">10</float>
+ <int key="IBUITextAlignment">1</int>
+ <object class="IBUIFontDescription" key="IBUIFontDescription">
+ <string key="name">Helvetica-Bold</string>
+ <string key="family">Helvetica</string>
+ <int key="traits">2</int>
+ <double key="pointSize">17</double>
+ </object>
+ <object class="NSFont" key="IBUIFont">
+ <string key="NSName">Helvetica-Bold</string>
+ <double key="NSSize">17</double>
+ <int key="NSfFlags">16</int>
+ </object>
+ </object>
+ </object>
+ <string key="NSFrame">{{0, 64}, {320, 416}}</string>
+ <reference key="NSSuperview"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="840199335"/>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ <object class="NSColorSpace" key="NSCustomColorSpace">
+ <int key="NSID">2</int>
+ </object>
+ </object>
+ <object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
+ <object class="IBUISimulatedNavigationBarMetrics" key="IBUISimulatedTopBarMetrics">
+ <bool key="IBUIPrompted">NO</bool>
+ </object>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ </object>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <object class="NSMutableArray" key="connectionRecords">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">view</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="191373211"/>
+ </object>
+ <int key="connectionID">3</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">timeLabel</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="840199335"/>
+ </object>
+ <int key="connectionID">12</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">coordinatesLabel</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="510191587"/>
+ </object>
+ <int key="connectionID">17</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">photoImageView</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="916784208"/>
+ </object>
+ <int key="connectionID">18</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">deletePhotoButton</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="1072420158"/>
+ </object>
+ <int key="connectionID">22</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">choosePhoto</string>
+ <reference key="source" ref="145267981"/>
+ <reference key="destination" ref="372490531"/>
+ <int key="IBEventType">1</int>
+ </object>
+ <int key="connectionID">23</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">deletePhoto</string>
+ <reference key="source" ref="1072420158"/>
+ <reference key="destination" ref="372490531"/>
+ <int key="IBEventType">1</int>
+ </object>
+ <int key="connectionID">24</int>
+ </object>
+ </object>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <object class="NSArray" key="orderedObjects">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <object class="NSArray" key="object" id="0">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <reference key="children" ref="1000"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">1</int>
+ <reference key="object" ref="191373211"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="510191587"/>
+ <reference ref="916784208"/>
+ <reference ref="840199335"/>
+ <reference ref="145267981"/>
+ <reference ref="1072420158"/>
+ </object>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="372490531"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">File's Owner</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="975951072"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">4</int>
+ <reference key="object" ref="916784208"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">5</int>
+ <reference key="object" ref="145267981"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">6</int>
+ <reference key="object" ref="510191587"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">8</int>
+ <reference key="object" ref="840199335"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">21</int>
+ <reference key="object" ref="1072420158"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="flattenedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>-1.CustomClassName</string>
+ <string>-1.IBPluginDependency</string>
+ <string>-2.CustomClassName</string>
+ <string>-2.IBPluginDependency</string>
+ <string>1.IBPluginDependency</string>
+ <string>21.IBPluginDependency</string>
+ <string>4.IBPluginDependency</string>
+ <string>5.IBPluginDependency</string>
+ <string>6.IBPluginDependency</string>
+ <string>8.IBPluginDependency</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>EventDetailViewController</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>UIResponder</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="unlocalizedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <reference key="dict.values" ref="0"/>
+ </object>
+ <nil key="activeLocalization"/>
+ <object class="NSMutableDictionary" key="localizations">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <reference key="dict.values" ref="0"/>
+ </object>
+ <nil key="sourceID"/>
+ <int key="maxID">24</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <object class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">EventDetailViewController</string>
+ <string key="superclassName">UIViewController</string>
+ <object class="NSMutableDictionary" key="actions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>choosePhoto</string>
+ <string>deletePhoto</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>id</string>
+ <string>id</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="actionInfosByName">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>choosePhoto</string>
+ <string>deletePhoto</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBActionInfo">
+ <string key="name">choosePhoto</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo">
+ <string key="name">deletePhoto</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="outlets">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>coordinatesLabel</string>
+ <string>deletePhotoButton</string>
+ <string>photoImageView</string>
+ <string>timeLabel</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>UILabel</string>
+ <string>UIButton</string>
+ <string>UIImageView</string>
+ <string>UILabel</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>coordinatesLabel</string>
+ <string>deletePhotoButton</string>
+ <string>photoImageView</string>
+ <string>timeLabel</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBToOneOutletInfo">
+ <string key="name">coordinatesLabel</string>
+ <string key="candidateClassName">UILabel</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">deletePhotoButton</string>
+ <string key="candidateClassName">UIButton</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">photoImageView</string>
+ <string key="candidateClassName">UIImageView</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">timeLabel</string>
+ <string key="candidateClassName">UILabel</string>
+ </object>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/EventDetailViewController.h</string>
+ </object>
+ </object>
+ </object>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+ <integer value="768" key="NS.object.0"/>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+ <real value="0.0" key="NS.object.0"/>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
+ <integer value="3000" key="NS.object.0"/>
+ </object>
+ <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ <string key="IBCocoaTouchPluginVersion">894</string>
+ </data>
+</archive>
24 Classes/LocationsAppDelegate.h
@@ -0,0 +1,24 @@
+
+/*
+ File: LocationsAppDelegate.h
+ Abstract: Application delegate to set up the Core Data stack and configure the view and navigation controllers.
+ Version: 1.1
+ */
+
+#import <Couchbase/CouchbaseEmbeddedServer.h>
+@class RootViewController, CouchServer;
+
+@interface LocationsAppDelegate : NSObject <UIApplicationDelegate, CouchbaseDelegate> {
+
+ UIWindow *window;
+ UINavigationController *navigationController;
+ RootViewController *rootViewController;
+}
+
+@property (nonatomic, retain) IBOutlet UIWindow *window;
+@property (nonatomic, retain) RootViewController *rootViewController;
+@property (nonatomic, retain) UINavigationController *navigationController;
+
+@property (nonatomic, retain) CouchServer *server;
+
+@end
101 Classes/LocationsAppDelegate.m
@@ -0,0 +1,101 @@
+
+/*
+ File: LocationsAppDelegate.m
+ Abstract: Application delegate to set up Couchbase Mobile and configure the view and navigation controllers.
+ Version: 1.1
+ */
+
+#import "LocationsAppDelegate.h"
+#import "RootViewController.h"
+#import <CouchCocoa/CouchCocoa.h>
+
+
+@implementation LocationsAppDelegate
+
+@synthesize window;
+@synthesize rootViewController;
+@synthesize navigationController;
+@synthesize server;
+
+
+#pragma mark -
+#pragma mark Application lifecycle
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+
+ // Configure and show the window.
+
+ self.rootViewController = [[[RootViewController alloc] initWithStyle:UITableViewStylePlain] autorelease];
+
+ // Initialize CouchDB:
+ CouchbaseEmbeddedServer* cb = [[CouchbaseEmbeddedServer alloc] init];
+ cb.delegate = self;
+ if (![cb start]) {
+ // TODO: Report error
+ NSLog(@"OMG: Couchbase couldn't start! Exiting! Error = %@", cb.error);
+ exit(1); // Panic!
+ }
+
+ UINavigationController *aNavigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
+ self.navigationController = aNavigationController;
+
+ [window addSubview:[navigationController view]];
+ [window makeKeyAndVisible];
+
+ [aNavigationController release];
+
+ return YES;
+}
+
+// This is the CouchbaseDelegate method called when the database starts up:
+-(void)couchbaseDidStart:(NSURL *)serverURL {
+ if (!serverURL) {
+ // TODO: Report error
+ NSLog(@"OMG: Couchbase couldn't start! Exiting!");
+ exit(1); // Panic!
+ }
+
+#ifdef DEBUG
+ NSLog(@"CouchDB is ready, go!");
+ gRESTLogLevel = kRESTLogRequestHeaders;
+#endif
+
+ self.server = [[[CouchServer alloc] initWithURL: serverURL] autorelease];
+ CouchDatabase* database = [self.server databaseNamed: @"locations"];
+
+ RESTOperation* op = [database create];
+ if (![op wait] && op.httpStatus != 412) { // 412 = Conflict; just means DB already exists
+ // TODO: Report error
+ NSLog(@"OMG: Couldn't create database: %@", op.error);
+ exit(1); // Panic!
+ }
+ rootViewController.database = database;
+}
+
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+ // Make sure all async operations complete before allowing the process to be suspended:
+ [RESTOperation wait: rootViewController.database.activeOperations];
+}
+
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+ // Make sure all async operations complete before quitting:
+ [RESTOperation wait: rootViewController.database.activeOperations];
+}
+
+
+#pragma mark -
+#pragma mark Memory management
+
+- (void)dealloc {
+
+ [server release];
+
+ [navigationController release];
+ [window release];
+ [super dealloc];
+}
+
+
+@end
31 Classes/RootViewController.h
@@ -0,0 +1,31 @@
+
+/*
+ File: RootViewController.h
+ Abstract: The table view controller responsible for displaying the list of events, supporting additional functionality:
+ * Addition of new new events;
+ * Deletion of existing events using UITableView's tableView:commitEditingStyle:forRowAtIndexPath: method.
+
+ Version: 1.1
+ */
+
+#import <CoreLocation/CoreLocation.h>
+@class CouchDatabase;
+
+@interface RootViewController : UITableViewController <CLLocationManagerDelegate> {
+
+ NSMutableArray *eventsArray;
+ CouchDatabase *database;
+
+ CLLocationManager *locationManager;
+ UIBarButtonItem *addButton;
+}
+
+@property (nonatomic, retain) NSMutableArray *eventsArray;
+@property (nonatomic, retain) CouchDatabase *database;
+
+@property (nonatomic, retain) CLLocationManager *locationManager;
+@property (nonatomic, retain) UIBarButtonItem *addButton;
+
+- (void)addEvent;
+
+@end
242 Classes/RootViewController.m
@@ -0,0 +1,242 @@
+
+/*
+ File: RootViewController.m
+ Abstract: The table view controller responsible for displaying the list of events, supporting additional functionality:
+ * Addition of new new events;
+ * Deletion of existing events using UITableView's tableView:commitEditingStyle:forRowAtIndexPath: method.
+ */
+
+#import "RootViewController.h"
+#import "LocationsAppDelegate.h"
+#import "Event.h"
+#import "EventDetailViewController.h"
+#import <CouchCocoa/CouchCocoa.h>
+
+
+@implementation RootViewController
+
+
+@synthesize eventsArray, addButton, locationManager;
+
+
+#pragma mark -
+#pragma mark View lifecycle
+
+- (void)viewDidLoad {
+
+ [super viewDidLoad];
+
+ // Set the title.
+ self.title = @"Locations";
+
+ // Configure the add and edit buttons.
+ self.navigationItem.leftBarButtonItem = self.editButtonItem;
+
+ addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addEvent)];
+ addButton.enabled = NO;
+ self.navigationItem.rightBarButtonItem = addButton;
+
+ // Start the location manager.
+ [[self locationManager] startUpdatingLocation];
+}
+
+
+// Called soon after launch as soon as the Couchbase database is ready
+- (void)setDatabase:(CouchDatabase *)aDatabase {
+ database = [aDatabase retain];
+
+ NSMutableArray *mutableFetchResults = [NSMutableArray array];
+ CouchQuery* query = [database getAllDocuments];
+ for (CouchQueryRow* row in [query rows]) {
+ Event* event = [[[Event alloc] initWithDocument:row.document] autorelease];
+ [mutableFetchResults addObject: event];
+ }
+
+ // Set self's events array to the mutable array, then clean up.
+ [self setEventsArray:mutableFetchResults];
+ [self.tableView reloadData];
+}
+
+
+- (CouchDatabase*)database {
+ return database;
+}
+
+
+- (void)viewWillAppear:(BOOL)animated {
+
+ [super viewWillAppear:animated];
+ [self.tableView reloadData];
+}
+
+
+- (void)viewDidUnload {
+ // Release any properties that are loaded in viewDidLoad or can be recreated lazily.
+ self.eventsArray = nil;
+ self.locationManager = nil;
+ self.addButton = nil;
+}
+
+
+#pragma mark -
+#pragma mark Table view data source methods
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
+ // Only one section.
+ return 1;
+}
+
+
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+ // As many rows as there are obects in the events array.
+ return [eventsArray count];
+}
+
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+
+ // A date formatter for the creation date.
+ static NSDateFormatter *dateFormatter = nil;
+ if (dateFormatter == nil) {
+ dateFormatter = [[NSDateFormatter alloc] init];
+ [dateFormatter setTimeStyle:NSDateFormatterMediumStyle];
+ [dateFormatter setDateStyle:NSDateFormatterShortStyle];
+ }
+
+ static NSString *CellIdentifier = @"Cell";
+
+ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
+ if (cell == nil) {
+ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
+ cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
+ }
+
+ // Get the event corresponding to the current index path and configure the table view cell.
+ Event *event = (Event *)[eventsArray objectAtIndex:indexPath.row];
+
+ cell.textLabel.text = [dateFormatter stringFromDate:[event creationDate]];
+ cell.imageView.image = event.thumbnail;
+
+ return cell;
+}
+
+
+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+
+ EventDetailViewController *inspector = [[EventDetailViewController alloc] initWithNibName:@"EventDetailViewController" bundle:nil];
+ inspector.event = [eventsArray objectAtIndex:indexPath.row];
+ [self.navigationController pushViewController:inspector animated:YES];
+ [inspector release];
+}
+
+
+/**
+ Handle deletion of an event.
+ */
+- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
+
+ if (editingStyle == UITableViewCellEditingStyleDelete) {
+
+ // Delete the managed object at the given index path.
+ Event *eventToDelete = [eventsArray objectAtIndex:indexPath.row];
+ [eventToDelete deleteDocument];
+
+ // Update the array and table view.
+ [eventsArray removeObjectAtIndex:indexPath.row];
+ [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
+ }
+}
+
+
+#pragma mark -
+#pragma mark Add an event
+
+/**
+ Add an event.
+ */
+- (void)addEvent {
+
+ // If it's not possible to get a location, then return.
+ CLLocation *location = [locationManager location];
+ if (!location) {
+ return;
+ }
+
+ /*
+ Create a new event document.
+ */
+
+ CLLocationCoordinate2D coordinate = [location coordinate];
+#if TARGET_IPHONE_SIMULATOR
+ // Location timestamp will be constant in the simulator.
+ NSDate* creationDate = [NSDate date];
+#else
+ NSDate* creationDate = [location timestamp];
+#endif
+
+ Event* event = [[[Event alloc] initWithDatabase:database
+ latitude:coordinate.latitude
+ longitude:coordinate.longitude
+ creationDate:creationDate] autorelease];
+
+ /*
+ Since this is a new event, and events are displayed with most recent events at the top of the list,
+ add the new event to the beginning of the events array; then redisplay the table view.
+ */
+ [eventsArray insertObject:event atIndex:0];
+ [self.tableView reloadData];
+ [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];
+}
+
+
+#pragma mark -
+#pragma mark Location manager
+
+/**
+ Return a location manager -- create one if necessary.
+ */
+- (CLLocationManager *)locationManager {
+
+ if (locationManager != nil) {
+ return locationManager;
+ }
+
+ locationManager = [[CLLocationManager alloc] init];
+ [locationManager setDesiredAccuracy:kCLLocationAccuracyNearestTenMeters];
+ [locationManager setDelegate:self];
+
+ return locationManager;
+}
+
+
+/**
+ Conditionally enable the Add button:
+ If the location manager is generating updates, then enable the button;
+ If the location manager is failing, then disable the button.
+ */
+- (void)locationManager:(CLLocationManager *)manager
+ didUpdateToLocation:(CLLocation *)newLocation
+ fromLocation:(CLLocation *)oldLocation {
+ addButton.enabled = YES;
+}
+
+- (void)locationManager:(CLLocationManager *)manager
+ didFailWithError:(NSError *)error {
+ addButton.enabled = NO;
+}
+
+
+#pragma mark -
+#pragma mark Memory management
+
+- (void)dealloc {
+ [database release];
+ [eventsArray release];
+ [locationManager release];
+ [addButton release];
+ [super dealloc];
+}
+
+
+@end
+
30 Info.plist
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleDisplayName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIconFile</key>
+ <string></string>
+ <key>CFBundleIdentifier</key>
+ <string>com.yourcompany.${PRODUCT_NAME:rfc1034identifier}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.1</string>
+ <key>LSRequiresIPhoneOS</key>
+ <true/>
+ <key>NSMainNibFile</key>
+ <string>MainWindow</string>
+</dict>
+</plist>
337 Locations.xcodeproj/project.pbxproj
@@ -0,0 +1,337 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 45;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 1D3623260D0F684500981E51 /* LocationsAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* LocationsAppDelegate.m */; };
+ 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; };
+ 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
+ 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };
+ 27853EC713DE2D0C00478EBB /* Couchbase.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 27853EC513DE2D0C00478EBB /* Couchbase.framework */; };
+ 27853EC813DE2D0C00478EBB /* CouchCocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 27853EC613DE2D0C00478EBB /* CouchCocoa.framework */; };
+ 27853ECA13DF411300478EBB /* libstdc++.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 27853EC913DF411300478EBB /* libstdc++.dylib */; };
+ 280681840FD61657002B1E65 /* EventDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 280681820FD61657002B1E65 /* EventDetailViewController.m */; };
+ 280681850FD61657002B1E65 /* EventDetailViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 280681830FD61657002B1E65 /* EventDetailViewController.xib */; };
+ 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */; };
+ 28A9E8BA0F43C7B50016529B /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28A9E8B90F43C7B50016529B /* CoreLocation.framework */; };
+ 28AD73600D9D9599002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD735F0D9D9599002E5188 /* MainWindow.xib */; };
+ 28B4FD790FD6D6F900AC17D8 /* ReadMe.txt in Resources */ = {isa = PBXBuildFile; fileRef = 28B4FD780FD6D6F900AC17D8 /* ReadMe.txt */; };
+ 28C286E10D94DF7D0034E888 /* RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28C286E00D94DF7D0034E888 /* RootViewController.m */; };
+ 28C95C640F4FB4660037F30F /* Event.m in Sources */ = {isa = PBXBuildFile; fileRef = 28C95C630F4FB4660037F30F /* Event.m */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+ 1D3623240D0F684500981E51 /* LocationsAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LocationsAppDelegate.h; path = Classes/LocationsAppDelegate.h; sourceTree = "<group>"; };
+ 1D3623250D0F684500981E51 /* LocationsAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = LocationsAppDelegate.m; path = Classes/LocationsAppDelegate.m; sourceTree = "<group>"; };
+ 1D6058910D05DD3D006BFB54 /* Locations.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Locations.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
+ 27853EC513DE2D0C00478EBB /* Couchbase.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Couchbase.framework; path = Frameworks/Couchbase.framework; sourceTree = "<group>"; };
+ 27853EC613DE2D0C00478EBB /* CouchCocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CouchCocoa.framework; path = Frameworks/CouchCocoa.framework; sourceTree = "<group>"; };
+ 27853EC913DF411300478EBB /* libstdc++.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libstdc++.dylib"; path = "usr/lib/gcc/arm-apple-darwin10/4.0.1/libstdc++.dylib"; sourceTree = SDKROOT; };
+ 280681810FD61657002B1E65 /* EventDetailViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventDetailViewController.h; sourceTree = "<group>"; };
+ 280681820FD61657002B1E65 /* EventDetailViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EventDetailViewController.m; sourceTree = "<group>"; };
+ 280681830FD61657002B1E65 /* EventDetailViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = EventDetailViewController.xib; sourceTree = "<group>"; };
+ 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
+ 28A0AAE50D9B0CCF005BE974 /* Locations_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Locations_Prefix.pch; sourceTree = "<group>"; };
+ 28A9E8B90F43C7B50016529B /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; };
+ 28AD735F0D9D9599002E5188 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = "<group>"; };
+ 28B4FD780FD6D6F900AC17D8 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = "<group>"; };
+ 28C286DF0D94DF7D0034E888 /* RootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RootViewController.h; sourceTree = "<group>"; };
+ 28C286E00D94DF7D0034E888 /* RootViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RootViewController.m; sourceTree = "<group>"; };
+ 28C95C620F4FB4660037F30F /* Event.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Event.h; path = Classes/Event.h; sourceTree = "<group>"; };
+ 28C95C630F4FB4660037F30F /* Event.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Event.m; path = Classes/Event.m; sourceTree = "<group>"; };
+ 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+ 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 1D60588F0D05DD3D006BFB54 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */,
+ 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */,
+ 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */,
+ 28A9E8BA0F43C7B50016529B /* CoreLocation.framework in Frameworks */,
+ 27853EC713DE2D0C00478EBB /* Couchbase.framework in Frameworks */,
+ 27853ECA13DF411300478EBB /* libstdc++.dylib in Frameworks */,
+ 27853EC813DE2D0C00478EBB /* CouchCocoa.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 080E96DDFE201D6D7F000001 /* View Controllers */ = {
+ isa = PBXGroup;
+ children = (
+ 28C286DF0D94DF7D0034E888 /* RootViewController.h */,
+ 28C286E00D94DF7D0034E888 /* RootViewController.m */,
+ 280681810FD61657002B1E65 /* EventDetailViewController.h */,
+ 280681820FD61657002B1E65 /* EventDetailViewController.m */,
+ 280681830FD61657002B1E65 /* EventDetailViewController.xib */,
+ );
+ name = "View Controllers";
+ path = Classes;
+ sourceTree = "<group>";
+ };
+ 19C28FACFE9D520D11CA2CBB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 1D6058910D05DD3D006BFB54 /* Locations.app */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 280681880FD618B9002B1E65 /* Model */ = {
+ isa = PBXGroup;
+ children = (
+ 28C95C620F4FB4660037F30F /* Event.h */,
+ 28C95C630F4FB4660037F30F /* Event.m */,
+ );
+ name = Model;
+ sourceTree = "<group>";
+ };
+ 28B4FC720FD63A7400AC17D8 /* Application */ = {
+ isa = PBXGroup;
+ children = (
+ 1D3623240D0F684500981E51 /* LocationsAppDelegate.h */,
+ 1D3623250D0F684500981E51 /* LocationsAppDelegate.m */,
+ 28AD735F0D9D9599002E5188 /* MainWindow.xib */,
+ 8D1107310486CEB800E47090 /* Info.plist */,
+ );
+ name = Application;
+ sourceTree = "<group>";
+ };
+ 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = {
+ isa = PBXGroup;
+ children = (
+ 28B4FD780FD6D6F900AC17D8 /* ReadMe.txt */,
+ 280681880FD618B9002B1E65 /* Model */,
+ 080E96DDFE201D6D7F000001 /* View Controllers */,
+ 28B4FC720FD63A7400AC17D8 /* Application */,
+ 29B97315FDCFA39411CA2CEA /* Other Sources */,
+ 29B97323FDCFA39411CA2CEA /* Frameworks */,
+ 19C28FACFE9D520D11CA2CBB /* Products */,
+ );
+ name = CustomTemplate;
+ sourceTree = "<group>";
+ };
+ 29B97315FDCFA39411CA2CEA /* Other Sources */ = {
+ isa = PBXGroup;
+ children = (
+ 28A0AAE50D9B0CCF005BE974 /* Locations_Prefix.pch */,
+ 29B97316FDCFA39411CA2CEA /* main.m */,
+ );
+ name = "Other Sources";
+ sourceTree = "<group>";
+ };
+ 29B97323FDCFA39411CA2CEA /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 27853EC513DE2D0C00478EBB /* Couchbase.framework */,
+ 27853EC613DE2D0C00478EBB /* CouchCocoa.framework */,
+ 28A9E8B90F43C7B50016529B /* CoreLocation.framework */,
+ 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */,
+ 1D30AB110D05D00D00671497 /* Foundation.framework */,
+ 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */,
+ 27853EC913DF411300478EBB /* libstdc++.dylib */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 1D6058900D05DD3D006BFB54 /* Locations */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "Locations" */;
+ buildPhases = (
+ 1D60588D0D05DD3D006BFB54 /* Resources */,
+ 27853ECB13DF41DB00478EBB /* Copy CouchDB */,
+ 1D60588E0D05DD3D006BFB54 /* Sources */,
+ 1D60588F0D05DD3D006BFB54 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = Locations;
+ productName = Locations;
+ productReference = 1D6058910D05DD3D006BFB54 /* Locations.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 29B97313FDCFA39411CA2CEA /* Project object */ = {
+ isa = PBXProject;
+ buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Locations" */;
+ compatibilityVersion = "Xcode 3.1";
+ developmentRegion = English;
+ hasScannedForEncodings = 1;
+ knownRegions = (
+ English,
+ Japanese,
+ French,
+ German,
+ en,
+ );
+ mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 1D6058900D05DD3D006BFB54 /* Locations */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 1D60588D0D05DD3D006BFB54 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 28AD73600D9D9599002E5188 /* MainWindow.xib in Resources */,
+ 280681850FD61657002B1E65 /* EventDetailViewController.xib in Resources */,
+ 28B4FD790FD6D6F900AC17D8 /* ReadMe.txt in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 27853ECB13DF41DB00478EBB /* Copy CouchDB */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Copy CouchDB";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "# The 'CouchbaseResources' subfolder of the framework contains Erlang code and other resources needed at runtime. Copy it into the app bundle:\nrsync -a \"${SRCROOT}/Frameworks/Couchbase.framework/CouchbaseResources\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}\"";
+ showEnvVarsInLog = 0;
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 1D60588E0D05DD3D006BFB54 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 1D60589B0D05DD56006BFB54 /* main.m in Sources */,
+ 1D3623260D0F684500981E51 /* LocationsAppDelegate.m in Sources */,
+ 28C286E10D94DF7D0034E888 /* RootViewController.m in Sources */,
+ 28C95C640F4FB4660037F30F /* Event.m in Sources */,
+ 280681840FD61657002B1E65 /* EventDetailViewController.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 1D6058940D05DD3E006BFB54 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ COPY_PHASE_STRIP = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "\"$(SRCROOT)/Frameworks\"",
+ );
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = Locations_Prefix.pch;
+ INFOPLIST_FILE = Info.plist;
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "\"$(SDKROOT)/usr/lib/gcc/arm-apple-darwin10/4.0.1\"",
+ );
+ PRODUCT_NAME = Locations;
+ };
+ name = Debug;
+ };
+ 1D6058950D05DD3E006BFB54 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ COPY_PHASE_STRIP = YES;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "\"$(SRCROOT)/Frameworks\"",
+ );
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = Locations_Prefix.pch;
+ INFOPLIST_FILE = Info.plist;
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "\"$(SDKROOT)/usr/lib/gcc/arm-apple-darwin10/4.0.1\"",
+ );
+ PRODUCT_NAME = Locations;
+ };
+ name = Release;
+ };
+ C01FCF4F08A954540054247B /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ GCC_C_LANGUAGE_STANDARD = c99;
+ GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1";
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ PREBINDING = NO;
+ SDKROOT = iphoneos4.0;
+ };
+ name = Debug;
+ };
+ C01FCF5008A954540054247B /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ GCC_C_LANGUAGE_STANDARD = c99;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ PREBINDING = NO;
+ SDKROOT = iphoneos4.0;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "Locations" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1D6058940D05DD3E006BFB54 /* Debug */,
+ 1D6058950D05DD3E006BFB54 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Locations" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C01FCF4F08A954540054247B /* Debug */,
+ C01FCF5008A954540054247B /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
+}
7 Locations.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+ version = "1.0">
+ <FileRef
+ location = "self:Locations.xcodeproj">
+ </FileRef>
+</Workspace>
10 Locations_Prefix.pch
@@ -0,0 +1,10 @@
+//
+// Prefix header for all source files of the 'Locations' target in the 'Locations' project
+//
+
+#import <Availability.h>
+
+#ifdef __OBJC__
+#import <Foundation/Foundation.h>
+#import <UIKit/UIKit.h>
+#endif
192 MainWindow.xib
@@ -0,0 +1,192 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.03">
+ <data>
+ <int key="IBDocument.SystemTarget">544</int>
+ <string key="IBDocument.SystemVersion">9G55</string>
+ <string key="IBDocument.InterfaceBuilderVersion">677</string>
+ <string key="IBDocument.AppKitVersion">949.43</string>
+ <string key="IBDocument.HIToolboxVersion">353.00</string>
+ <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSArray" key="IBDocument.PluginDependencies">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBProxyObject" id="841351856">
+ <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+ </object>
+ <object class="IBProxyObject" id="302016328">
+ <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+ </object>
+ <object class="IBUICustomObject" id="664661524"/>
+ <object class="IBUIWindow" id="380026005">
+ <nil key="NSNextResponder"/>
+ <int key="NSvFlags">1316</int>
+ <object class="NSPSMatrix" key="NSFrameMatrix"/>
+ <string key="NSFrameSize">{320, 480}</string>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MSAxIDEAA</bytes>
+ </object>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+ <object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
+ </object>
+ </object>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <object class="NSMutableArray" key="connectionRecords">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">delegate</string>
+ <reference key="source" ref="841351856"/>
+ <reference key="destination" ref="664661524"/>
+ </object>
+ <int key="connectionID">4</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">window</string>
+ <reference key="source" ref="664661524"/>
+ <reference key="destination" ref="380026005"/>
+ </object>
+ <int key="connectionID">5</int>
+ </object>
+ </object>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <object class="NSArray" key="orderedObjects">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <object class="NSArray" key="object" id="957960031">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <reference key="children" ref="1000"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">2</int>
+ <reference key="object" ref="380026005"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <reference key="parent" ref="957960031"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="841351856"/>
+ <reference key="parent" ref="957960031"/>
+ <string type="base64-UTF8" key="objectName">RmlsZSdzIE93bmVyA</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">3</int>
+ <reference key="object" ref="664661524"/>
+ <reference key="parent" ref="957960031"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="302016328"/>
+ <reference key="parent" ref="957960031"/>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="flattenedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSMutableArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>-1.CustomClassName</string>
+ <string>-2.CustomClassName</string>
+ <string>2.IBAttributePlaceholdersKey</string>
+ <string>2.IBEditorWindowLastContentRect</string>
+ <string>2.IBPluginDependency</string>
+ <string>3.CustomClassName</string>
+ <string>3.IBPluginDependency</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>UIApplication</string>
+ <string>UIResponder</string>
+ <object class="NSMutableDictionary">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <string>{{673, 376}, {320, 480}}</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>LocationsAppDelegate</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="unlocalizedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="activeLocalization"/>
+ <object class="NSMutableDictionary" key="localizations">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="sourceID"/>
+ <int key="maxID">15</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <object class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">LocationsAppDelegate</string>
+ <string key="superclassName">NSObject</string>
+ <object class="NSMutableDictionary" key="actions">
+ <string key="NS.key.0">saveAction:</string>
+ <string key="NS.object.0">id</string>
+ </object>
+ <object class="NSMutableDictionary" key="outlets">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSMutableArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>navigationController</string>
+ <string>window</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>UINavigationController</string>
+ <string>UIWindow</string>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/LocationsAppDelegate.h</string>
+ </object>
+ </object>
+ </object>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.LastKnownRelativeProjectPath">Locations.xcodeproj</string>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ </data>
+</archive>
59 ReadMe.txt
@@ -0,0 +1,59 @@
+
+### PhotoLocations ###
+
+===========================================================================
+DESCRIPTION:
+
+This sample illustrates an iOS application that uses Mobile Couchbase to store local data, including binary attachments. It is adapted from Apple's PhotoLocations sample app, with the CoreData model code replaced by CouchCocoa API calls.
+
+The first screen displays a table view of events, which encapsulate a time stamp, a geographical location expressed in latitude and longitude, and the thumbnail of a picture for the event. The user can add and remove events using the first screen.
+
+The data model is simple: Each event is a CouchDB document with attributes for the time stamp and location. The picture is stored as an attachment, so it can be retrieved separately from the document; but a small thumbnail is stored inline in the document (as a base64-encoded string) since it's needed whenever the event is shown.
+
+
+===========================================================================
+BUILD REQUIREMENTS:
+
+Mac OS X v10.6.8 or later; Xcode 4.0 or later; iOS 4.0 or later.
+Couchbase.framework (download from https://github.com/couchbaselabs/iOS-Couchbase)
+CouchCocoa.framework (build from https://github.com/couchbaselabs/CouchCocoa)
+
+Before building the app, copy Couchbase.framework and CouchCocoa.framework into the "Frameworks" subfolder.
+
+===========================================================================
+RUNTIME REQUIREMENTS:
+
+iOS 4.0 or later.
+
+===========================================================================
+PACKAGING LIST:
+
+View Controllers
+----------------
+
+RootViewController.{h,m}
+The table view controller responsible for displaying the list of events, supporting additional functionality:
+ * Addition of new new events;
+ * Deletion of existing events using UITableView's tableView:commitEditingStyle:forRowAtIndexPath: method.
+
+
+EventDetailViewController.{h,m}
+EventDetailViewController.xib
+The table view controller responsible for displaying the time, coordinates, and photo of an event, and allowing the user to select a photo for the event, or delete the existing photo.
+
+
+Model
+-----
+
+Event.{h,m}
+A class to represent an event containing geographical coordinates, a time stamp, and an image.
+
+
+Application configuration
+-------------------------
+
+LocationsAppDelegate.{h,m}
+Configures Mobile Couchbase and the first view controller.
+
+MainWindow.xib
+Loaded automatically by the application. Creates the application's delegate and window.
17 main.m
@@ -0,0 +1,17 @@
+
+/*
+ File: main.m
+ Abstract: Standard application main.m.
+
+ Version: 1.1
+ */
+
+#import <UIKit/UIKit.h>
+
+int main(int argc, char *argv[]) {
+
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+ int retVal = UIApplicationMain(argc, argv, nil, nil);
+ [pool release];
+ return retVal;
+}

0 comments on commit 89b3e75

Please sign in to comment.