Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

First commit

  • Loading branch information...
commit fe0b3d9e0ac7e6d7bc0bf672137b0840164d424b 0 parents
alunny authored
Showing with 9,231 additions and 0 deletions.
  1. +27 −0 Classes/Contacts.h
  2. +86 −0 Classes/Contacts.m
  3. +16 −0 Classes/Device.h
  4. +47 −0 Classes/Device.m
  5. +18 −0 Classes/File.h
  6. +14 −0 Classes/File.m
  7. +31 −0 Classes/Image.h
  8. +159 −0 Classes/Image.m
  9. +36 −0 Classes/Location.h
  10. +96 −0 Classes/Location.m
  11. +56 −0 Classes/PhoneGapDelegate.h
  12. +478 −0 Classes/PhoneGapDelegate.m
  13. +20 −0 Classes/PhoneGapViewController.h
  14. +48 −0 Classes/PhoneGapViewController.m
  15. +19 −0 Classes/Sound.h
  16. +34 −0 Classes/Sound.m
  17. +17 −0 Classes/Vibrate.h
  18. +26 −0 Classes/Vibrate.m
  19. BIN  Default.png
  20. +30 −0 Info.plist
  21. +324 −0 MainWindow.xib
  22. +8 −0 PhoneGap_Prefix.pch
  23. +1,413 −0 Pigeon.xcodeproj/andrewlunny.mode1v3
  24. +429 −0 Pigeon.xcodeproj/andrewlunny.pbxuser
  25. +1,425 −0 Pigeon.xcodeproj/brianleroux.mode1v3
  26. +1,493 −0 Pigeon.xcodeproj/eric.mode1v3
  27. +1,471 −0 Pigeon.xcodeproj/nitobi.mode1v3
  28. +379 −0 Pigeon.xcodeproj/project.pbxproj
  29. +3 −0  README.md
  30. +12 −0 Settings.plist
  31. BIN  beep.wav
  32. BIN  icon.png
  33. +10 −0 main.m
  34. +116 −0 www/index.html
  35. +68 −0 www/master.css
  36. +665 −0 www/script/phonegap.js
  37. +69 −0 www/script/pigeon.js
  38. +87 −0 www/script/sql.js
  39. +1 −0  www/script/xui-min.js
27 Classes/Contacts.h
@@ -0,0 +1,27 @@
+/*
+ * Contact.h
+ *
+ * Created by Nitobi on 12/12/08.
+ * Copyright 2008 Nitobi. All rights reserved.
+ *
+ */
+
+#import <Foundation/Foundation.h>
+#import <AddressBook/ABAddressBook.h>
+
+@interface Contacts : NSObject {
+ ABAddressBookRef addressBook;
+ NSArray *allPeople;
+ CFIndex nPeople;
+}
+
+@property (getter=getAddressBook,assign) ABAddressBookRef addressBook;
+@property (getter=getContacts,assign) NSArray *allPeople;
+
+//- (NSString *)stringValueForRow:(NSInteger)row;
+
+- (id)init;
+- (void) displayContact:(ABRecordRef *) person;
+- (void) addContact;
+
+@end
86 Classes/Contacts.m
@@ -0,0 +1,86 @@
+/*
+ * Contact.m
+ *
+ * Created by Nitobi on 2/3/09
+ * Copyright 2008 Nitobi. All rights reserved.
+ * Rob Ellis rob.ellis@nitobi.com
+ *
+ */
+
+
+#import <AddressBook/AddressBook.h>
+#import "Contacts.h"
+
+@implementation Contacts
+
+@synthesize addressBook;
+@synthesize allPeople;
+
+- (id)init
+{
+ self = [super init];
+ addressBook = ABAddressBookCreate();
+ return self;
+}
+
+- (NSMutableString *)getContacts {
+ NSMutableString *update = [[[NSMutableString alloc] init] autorelease];
+
+ if (allPeople == nil) {
+ allPeople = (NSArray *)ABAddressBookCopyArrayOfAllPeople(self.addressBook);
+ CFIndex numberOfPeople = ABAddressBookGetPersonCount(self.addressBook);
+
+ [update appendString:@"var _contacts=["];
+
+ for (int i=0;i < numberOfPeople;i++) {
+ ABRecordRef ref = CFArrayGetValueAtIndex(allPeople,i);
+
+ if (ABRecordCopyValue(ref, kABPersonFirstNameProperty) != nil && ABRecordCopyValue(ref, kABPersonLastNameProperty) != nil) {
+ CFStringRef firstName = ABRecordCopyValue(ref, kABPersonFirstNameProperty);
+ CFStringRef lastName = ABRecordCopyValue(ref, kABPersonLastNameProperty);
+ CFStringRef phoneNumber = ABMultiValueCopyValueAtIndex(ABRecordCopyValue(ref,kABPersonPhoneProperty) ,0);
+
+ NSString *contactFirstLast = [NSString stringWithFormat:@"%@ %@",firstName, lastName];
+ NSString *contactFirstLast2 = [NSString stringWithFormat:@"{'name':'%@','phone':'%@'}",contactFirstLast,phoneNumber];
+ [update appendFormat:@"%@", contactFirstLast2];
+ if (i+1 != numberOfPeople) {
+ [update appendFormat:@","];
+ }
+
+ CFRelease(firstName);
+ CFRelease(lastName);
+ CFRelease(phoneNumber);
+ }
+ }
+
+ [update appendString:@"];"];
+ }
+ return update;
+}
+
+- (void) addContact {
+
+ ABAddressBookRef libroDirec = ABAddressBookCreate();
+ ABRecordRef persona = ABPersonCreate();
+
+ ABRecordSetValue(persona, kABPersonFirstNameProperty, @"kate" , nil);
+ ABRecordSetValue(persona, kABPersonLastNameProperty, @"Hutson", nil);
+ ABAddressBookAddRecord(libroDirec, persona, nil);
+ ABAddressBookSave(libroDirec, nil);
+
+ CFRelease(persona);
+}
+
+
+- (void) displayContact:(ABRecordRef *) person {
+ NSLog(@"HERE");
+}
+
+- (ABAddressBookRef)getAddressBook {
+ if (nil == addressBook)
+ {
+ addressBook = ABAddressBookCreate();
+ }
+ return addressBook;
+}
+@end
16 Classes/Device.h
@@ -0,0 +1,16 @@
+/*
+ * Device.h
+ * Used to display Device centric details handset.
+ *
+ * Created by Nitobi on 12/12/08.
+ * Copyright 2008 Nitobi. All rights reserved.
+ */
+
+#import <UIKit/UIKit.h>
+#import <UIKit/UIDevice.h>
+
+@interface Device : NSObject {
+ UIDevice *myCurrentDevice;
+}
+
+@end
47 Classes/Device.m
@@ -0,0 +1,47 @@
+/*
+ * Device.m
+ * Used to display Device centric details handset.
+ *
+ * Created by Nitobi on 12/12/08.
+ * Copyright 2008 Nitobi. All rights reserved.
+ */
+
+#import "Device.h"
+
+@implementation Device
+
+/*
+ * init
+ * returns a JS String with various device settings
+ * - gap enabled
+ * - version
+ * - Device model
+ * - Device Version
+ * - Device UUID
+ */
+- (NSString *)init{
+
+ myCurrentDevice = [UIDevice currentDevice];
+//
+// return jsCallBack = [[NSString alloc] initWithFormat:@"\
+// __gap = true; \
+// __gap_version='0.2'; \
+// __gap_device_model='%s'; \
+// __gap_device_version='%s';\
+// __gap_device_uniqueid='%s';",
+// [[myCurrentDevice model] UTF8String],
+// [[myCurrentDevice systemVersion] UTF8String],
+// [[myCurrentDevice uniqueIdentifier] UTF8String]
+// ];
+
+
+ return [[NSString alloc] initWithFormat:@"Device={};Device.platform='%s';Device.version='%s';Device.uuid='%s';",[[myCurrentDevice model] UTF8String], [[myCurrentDevice systemVersion] UTF8String], [[myCurrentDevice uniqueIdentifier] UTF8String] ];
+}
+
+- (void)dealloc {
+ [myCurrentDevice release];
+ [super dealloc];
+
+}
+
+@end
18 Classes/File.h
@@ -0,0 +1,18 @@
+//
+// File.h
+// PhoneGap
+//
+// Created by Nitobi on 19/12/08.
+// Copyright 2008 Nitobi. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+
+@interface File : NSObject {
+
+}
+
+
+
+@end
14 Classes/File.m
@@ -0,0 +1,14 @@
+//
+// File.m
+// PhoneGap
+//
+// Created by Nitobi on 19/12/08.
+// Copyright 2008 Nitobi. All rights reserved.
+//
+
+#import "File.h"
+
+
+@implementation File
+
+@end
31 Classes/Image.h
@@ -0,0 +1,31 @@
+/*
+ * Image.h
+ * PhoneGap
+ *
+ * Created by Nitobi on 04/02/09.
+ * Copyright 2009 Nitobi. All rights reserved.
+ *
+ */
+
+#import <Foundation/Foundation.h>
+
+
+@interface Image : NSObject {
+ IBOutlet UIWindow *window;
+ IBOutlet UIWebView *webView;
+
+ UIImagePickerController *picker; // added by urbian
+ NSString *photoUploadUrl; // added by urbian
+ NSString *lastUploadedPhoto; // added by urbian
+ NSURLConnection *conn; // added by urbian
+ NSMutableData *receivedData; // added by urbian
+
+}
+
+@property (nonatomic, retain) UIImagePickerController *imagePickerController;
+@property (nonatomic, retain) UIWindow *window;
+
+- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image2 editingInfo:(NSDictionary *)editingInfo;
+- (void) imagePickerControllerDidCancel:(UIImagePickerController *)picker;
+
+@end
159 Classes/Image.m
@@ -0,0 +1,159 @@
+/*
+ * Image.m
+ * PhoneGap
+ *
+ * Created by Nitobi on 04/02/09.
+ * Copyright 2009 Nitobi. All rights reserved.
+ * Rob Ellis * Brian LeRoux * Brock Whitten
+ *
+ * Special thanks to urbian.org - g.mueller @urbian.org
+ *
+ */
+
+#import "Image.h"
+
+@implementation Image
+
+@synthesize window;
+
+// TODO Move to Image.m
+- (void)imagePickerController:(UIImagePickerController *)thePicker didFinishPickingImage:(UIImage *)theImage editingInfo:(NSDictionary *)editingInfo
+{
+
+ //modified by urbian.org - g.mueller @urbian.org
+
+ NSLog(@"photo: picked image");
+
+ NSData * imageData = UIImageJPEGRepresentation(theImage, 0.75);
+
+ NSString *urlString = [@"http://" stringByAppendingString:photoUploadUrl]; // upload the photo to this url
+
+ NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
+ [request setURL:[NSURL URLWithString:urlString]];
+ [request setHTTPMethod:@"POST"];
+
+ // ---------
+ //Add the header info
+ NSString *stringBoundary = [NSString stringWithString:@"0xKhTmLbOuNdArY"];
+ NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",stringBoundary];
+ [request addValue:contentType forHTTPHeaderField: @"Content-Type"];
+
+ //create the body
+ NSMutableData *postBody = [NSMutableData data];
+ [postBody appendData:[[NSString stringWithFormat:@"--%@\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
+
+ //add data field and file data
+ [postBody appendData:[[NSString stringWithString:@"Content-Disposition: form-data; name=\"photo_0\"; filename=\"photo\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
+ [postBody appendData:[[NSString stringWithString:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
+
+ [postBody appendData:[NSData dataWithData:imageData]];
+ [postBody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
+
+ // ---------
+ [request setHTTPBody:postBody];
+
+ //NSURLConnection *
+ conn=[[NSURLConnection alloc] initWithRequest:request delegate:self];
+
+ if(conn) {
+ receivedData=[[NSMutableData data] retain];
+ NSString *sourceSt = [[NSString alloc] initWithBytes:[receivedData bytes] length:[receivedData length] encoding:NSUTF8StringEncoding];
+ NSLog([@"photo: connection sucess" stringByAppendingString:sourceSt]);
+
+ } else {
+ NSLog(@"photo: upload failed!");
+ }
+
+ [[thePicker parentViewController] dismissModalViewControllerAnimated:YES];
+
+ webView.hidden = NO;
+ [window bringSubviewToFront:webView];
+
+}
+
+
+// TODO Move to Image.m
+- (void)imagePickerControllerDidCancel:(UIImagePickerController *)thePicker
+{
+ // Dismiss the image selection and close the program
+ [[thePicker parentViewController] dismissModalViewControllerAnimated:YES];
+
+ //added by urbian - the webapp should know when the user canceled
+ NSString * jsCallBack = nil;
+
+ jsCallBack = [[NSString alloc] initWithFormat:@"gotPhoto('CANCEL');", lastUploadedPhoto];
+ [webView stringByEvaluatingJavaScriptFromString:jsCallBack];
+ [jsCallBack release];
+
+ // Hide the imagePicker and bring the web page back into focus
+ NSLog(@"Photo Cancel Request");
+ webView.hidden = NO;
+ [window bringSubviewToFront:webView];
+}
+
+
+
+// TODO Move to Image.m
+- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
+
+ NSLog(@"photo: upload finished!");
+
+ //added by urbian.org - g.mueller
+ NSString *aStr = [[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding];
+
+ //upload.php should return "filename=<filename>"
+ NSLog(aStr);
+ NSArray * parts = [aStr componentsSeparatedByString:@"="];
+ //set filename
+ lastUploadedPhoto = (NSString *)[parts objectAtIndex:1];
+
+ //now the callback: return lastUploadedPhoto
+
+ NSString * jsCallBack = nil;
+
+ if(lastUploadedPhoto == nil) lastUploadedPhoto = @"ERROR";
+
+ jsCallBack = [[NSString alloc] initWithFormat:@"gotPhoto('%@');", lastUploadedPhoto];
+
+ [webView stringByEvaluatingJavaScriptFromString:jsCallBack];
+
+ NSLog(@"Succeeded! Received %d bytes of data",[receivedData length]);
+ NSLog(jsCallBack);
+
+ // release the connection, and the data object
+ [conn release];
+ [receivedData release];
+
+}
+
+
+// TODO Move to Image.m
+-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *) response {
+
+ //added by urbian.org
+ NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
+ NSLog(@"HTTP Status Code: %i", [httpResponse statusCode]);
+
+ [receivedData setLength:0];
+}
+
+- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
+{
+ // append the new data to the receivedData
+ // receivedData is declared as a method instance elsewhere
+ [receivedData appendData:data];
+ NSLog(@"photo: progress");
+}
+
+
+/*
+ * Failed with Error
+ */
+- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
+ NSLog([@"photo: upload failed! " stringByAppendingString:[error description]]);
+
+}
+
+
+
+@end
36 Classes/Location.h
@@ -0,0 +1,36 @@
+/*
+ * Location.h
+ *
+ * Created by Nitobi on 12/12/08.
+ * Copyright 2008 Nitobi. All rights reserved.
+ *
+ */
+
+#import <UIKit/UIKit.h>
+#import <CoreLocation/CoreLocation.h>
+
+@protocol LocationDelegate <NSObject>
+@required
+@end
+
+
+@interface Location : NSObject <CLLocationManagerDelegate> {
+ CLLocationManager *locationManager;
+ CLLocation *lastKnownLocation;
+ id delegate;
+
+}
+
+@property (nonatomic, retain) CLLocation *lastKnownLocation;
+@property (nonatomic, retain) CLLocationManager *locationManager;
+@property (nonatomic,assign) id <LocationDelegate> delegate;
+
+- (NSString *) getPosition;
+
+- (void)locationManager:(CLLocationManager *)manager
+ didUpdateToLocation:(CLLocation *)newLocation
+ fromLocation:(CLLocation *)oldLocation;
+
++ (Location *)sharedInstance;
+
+@end
96 Classes/Location.m
@@ -0,0 +1,96 @@
+/*
+ * Location.m
+ *
+ * Created by Nitobi on 12/12/08.
+ * Copyright 2008 Nitobi. All rights reserved.
+ *
+ */
+
+#import "Location.h"
+
+#define LocStr(key) [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:nil]
+
+@implementation Location
+@synthesize locationManager;
+@synthesize lastKnownLocation;
+
+static Location *sharedCLDelegate = nil;
+
+
+- (id) init {
+ self = [super init];
+ if (self != nil) {
+ self.locationManager = [[[CLLocationManager alloc] init] autorelease];
+ self.locationManager.delegate = self; // Tells the location manager to send updates to this object
+ }
+ return self;
+}
+
+
+- (void)locationManager:(CLLocationManager *)manager
+ didUpdateToLocation:(CLLocation *)newLocation
+ fromLocation:(CLLocation *)oldLocation
+{
+ [lastKnownLocation release];
+ lastKnownLocation = newLocation;
+ [lastKnownLocation retain];
+}
+
+
+- (NSString *)getPosition
+{
+
+ return [[NSString alloc] initWithFormat:@"var geo={lat:%f,lng:%f,alt:%f};",
+ lastKnownLocation.coordinate.latitude,
+ lastKnownLocation.coordinate.longitude,
+ lastKnownLocation.altitude];
+
+}
+
++ (Location *)sharedInstance {
+ @synchronized(self) {
+ if (sharedCLDelegate == nil) {
+ [[self alloc] init]; // assignment not done here
+ }
+ }
+ return sharedCLDelegate;
+}
+
++ (id)allocWithZone:(NSZone *)zone {
+ @synchronized(self) {
+ if (sharedCLDelegate == nil) {
+ sharedCLDelegate = [super allocWithZone:zone];
+ return sharedCLDelegate; // assignment and return on first allocation
+ }
+ }
+ return nil; // on subsequent allocation attempts return nil
+}
+
+- (id)copyWithZone:(NSZone *)zone
+{
+ return self;
+}
+
+- (id)retain {
+ return self;
+}
+
+- (unsigned)retainCount {
+ return UINT_MAX; // denotes an object that cannot be released
+}
+
+- (void)release {
+ //do nothing
+}
+
+- (id)autorelease {
+ return self;
+}
+
+
+- (void)dealloc {
+ [locationManager release];
+ [super dealloc];
+}
+
+@end
56 Classes/PhoneGapDelegate.h
@@ -0,0 +1,56 @@
+
+#import <UIKit/UIKit.h>
+#import <CoreLocation/CoreLocation.h>
+#import <UIKit/UINavigationController.h>
+
+#import "Vibrate.h"
+#import "Location.h"
+#import "Device.h"
+#import "Sound.h"
+#import "Contacts.h"
+//#import "Image.h"
+
+@class PhoneGapViewController;
+@class Sound;
+@class Contacts;
+//@class Image;
+
+@interface PhoneGapDelegate : NSObject <
+ UIApplicationDelegate,
+ UIWebViewDelegate,
+ UIAccelerometerDelegate,
+ UIImagePickerControllerDelegate,
+ UIPickerViewDelegate,
+ UINavigationControllerDelegate
+ >
+{
+
+ IBOutlet UIWindow *window;
+ IBOutlet PhoneGapViewController *viewController;
+ IBOutlet UIWebView *webView;
+
+ IBOutlet UIImageView *imageView;
+ IBOutlet UIActivityIndicatorView *activityView;
+
+ UIImagePickerController *picker; // added by urbian
+ NSString *photoUploadUrl; // added by urbian
+ NSString *lastUploadedPhoto; // added by urbian
+ NSURLConnection *conn; // added by urbian
+ NSMutableData *receivedData; // added by urbian
+
+ UIImagePickerController *imagePickerController;
+
+ NSURLConnection *callBackConnection;
+ Sound *sound;
+ Contacts *contacts;
+ NSURL* appURL;
+}
+
+@property (nonatomic, retain) UIWindow *window;
+@property (nonatomic, retain) PhoneGapViewController *viewController;
+@property (nonatomic, retain) UIImagePickerController *imagePickerController;
+
+//- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image2 editingInfo:(NSDictionary *)editingInfo;
+//- (void) imagePickerControllerDidCancel:(UIImagePickerController *)picker;
+
+@end
478 Classes/PhoneGapDelegate.m
@@ -0,0 +1,478 @@
+#import "PhoneGapDelegate.h"
+#import "PhoneGapViewController.h"
+#import <UIKit/UIKit.h>
+
+@implementation PhoneGapDelegate
+
+@synthesize window;
+@synthesize viewController;
+
+@synthesize imagePickerController;
+
+void alert(NSString *message) {
+// UIAlertView *openURLAlert = [[UIAlertView alloc] initWithTitle:@"Alert" message:message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
+// [openURLAlert show];
+// [openURLAlert release];
+}
+
+/*
+ * applicationDidFinishLaunching
+ * This is main kick off after the app inits, the views and Settings are setup here.
+ */
+
+
+- (void)applicationDidFinishLaunching:(UIApplication *)application {
+
+ /*
+ * Fire up the GPS Service right away as it takes a moment for data to come back.
+ */
+ [[Location sharedInstance].locationManager startUpdatingLocation];
+
+ webView.delegate = self;
+
+ // Set up the image picker controller and add it to the view
+ imagePickerController = [[UIImagePickerController alloc] init];
+ imagePickerController.delegate = self;
+ imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
+ imagePickerController.view.hidden = YES;
+
+ [[UIAccelerometer sharedAccelerometer] setUpdateInterval:1.0/40.0];
+ [[UIAccelerometer sharedAccelerometer] setDelegate:self];
+
+ [window addSubview:viewController.view];
+
+ NSString *errorDesc = nil;
+
+
+ /*
+ * Settings.plist
+ *
+ * This block of code navigates to the Settings.plist in the Config Group and reads the XML into an Hash (Dictionary)
+ *
+ */
+ NSPropertyListFormat format;
+ NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"Settings" ofType:@"plist"];
+ NSData *plistXML = [[NSFileManager defaultManager] contentsAtPath:plistPath];
+ NSDictionary *temp = (NSDictionary *)[NSPropertyListSerialization
+ propertyListFromData:plistXML
+ mutabilityOption:NSPropertyListMutableContainersAndLeaves
+ format:&format errorDescription:&errorDesc];
+
+ NSString *offline = [temp objectForKey:@"Offline"];
+ NSString *url = [temp objectForKey:@"Callback"];
+ int *detectNumber = [temp objectForKey:@"DetectPhoneNumber"];
+
+
+
+
+ /*
+ * We want to test the offline to see if this app should start in offline mode or online mode.
+ *
+ * 0 - Offline
+ * 1 - Online
+ *
+ * In Offline mode the index.html file is loaded from the www directly and serves as the entry point into the application
+ * In Online mode the starting point is a external FQDN, usually your server.
+ */
+ if ([offline isEqualToString:@"0"]) {
+ appURL = [[NSURL URLWithString:url] retain];
+ } else {
+ NSBundle * thisBundle = [NSBundle bundleForClass:[self class]];
+ appURL = [[NSURL fileURLWithPath:[thisBundle pathForResource:@"index" ofType:@"html" inDirectory:@"www"]] retain];
+ }
+
+
+ /*
+ * webView
+ * This is where we define the inital instance of the browser (WebKit) and give it a starting url/file.
+ */
+ [webView loadRequest:[NSURLRequest
+ requestWithURL:appURL
+ cachePolicy:NSURLRequestUseProtocolCachePolicy
+ timeoutInterval:20.0
+ ]];
+
+
+ /*
+ * detectNumber - If we want to Automagicly convery phone numbers to links - Set in Settings.plist
+ * Value should be BOOL (YES|NO)
+ *
+ * For whatever reason this quit working
+ */
+ webView.detectsPhoneNumbers=detectNumber;
+
+
+ /*
+ * imageView - is the Default loading screen, it stay up until the app and UIWebView (WebKit) has completly loaded.
+ * You can change this image by swapping out the Default.png file within the resource folder.
+ */
+ imageView = [[UIImageView alloc] initWithImage:[[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Default" ofType:@"png"]]];
+ [window addSubview:imageView];
+
+
+ /*
+ * These are the setting for the top Status/Battery Bar.
+ *
+ * UIStatusBarStyleBlackOpaque
+ * UIStatusBarStyleBlackTranslucent
+ * UIStatusBarStyleDefault - Default
+ *
+ */
+ [application setStatusBarStyle:UIStatusBarStyleBlackOpaque animated:NO];
+
+
+ /*
+ * The Activity View is the top spinning throbber in the status/battery bar. We init it with the default Grey Style.
+ *
+ * UIActivityIndicatorViewStyleWhiteLarge
+ * UIActivityIndicatorViewStyleWhite
+ * UIActivityIndicatorViewStyleGray
+ *
+ */
+ activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
+ [window addSubview:activityView];
+ [activityView startAnimating];
+
+
+ /*
+ * If you don't want your app to have a status bar, just uncomment this.
+ */
+ //[[UIApplication sharedApplication] setStatusBarHidden:YES animated:NO];
+
+
+ [window makeKeyAndVisible];
+
+}
+
+
+/*
+ * When web application loads Add stuff to the DOM (HTML 5)
+ */
+- (void)webViewDidStartLoad:(UIWebView *)theWebView {
+
+ /*
+ * This is the Device.plaftorm information
+ */
+ [theWebView stringByEvaluatingJavaScriptFromString:[[Device alloc] init]];
+
+}
+
+- (void)webViewDidFinishLoad:(UIWebView *)theWebView {
+ /*
+ * Hide the Top Activity THROBER in the Battery Bar
+ */
+ [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
+ activityView.hidden = YES;
+
+ imageView.hidden = YES;
+
+ [window bringSubviewToFront:viewController.view];
+ webView = theWebView;
+}
+
+
+/*
+ * - Fail Loading With Error
+ * Error - If the webpage failed to load display an error with the reson.
+ *
+ */
+- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
+ if ([error code] != NSURLErrorCancelled)
+ alert(error.localizedDescription);
+}
+
+
+/*
+ * Start Loading Request
+ * This is where most of the magic happens... We take the request(s) and process the response.
+ * From here we can re direct links and other protocalls to different internal methods.
+ *
+ */
+- (BOOL)webView:(UIWebView *)theWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
+
+ NSURL * url = [request URL];
+
+ // Check to see if the URL request is for the App URL.
+ // If it is not, then launch using Safari
+ // TODO: There was a suggestion to check this against a whitelist of urls, this would be a good place to do that.
+ NSString * urlHost = [url host];
+ NSString * appHost = [appURL host];
+ NSRange range = [urlHost rangeOfString:appHost options:NSCaseInsensitiveSearch];
+
+ if ([[url scheme] isEqualToString:@"gap"]) {
+
+ NSString * path = [url path];
+ /*
+ * Get Command and Options From URL
+ * We are looking for URLS that match gap://<command>[/<options>]
+ * We have to strip off the leading slah for the options.
+ */
+ NSString * command = [url host];
+
+ NSString * options = [path substringWithRange:NSMakeRange(1, [path length] - 1)];
+
+ NSString * jsCallBack = nil;
+
+ if([command isEqualToString:@"getloc"]){
+ jsCallBack = [[Location sharedInstance] getPosition];
+
+ [theWebView stringByEvaluatingJavaScriptFromString:jsCallBack];
+ [jsCallBack release];
+
+ } else if([command isEqualToString:@"vibrate"]){
+ /*
+ * Make the device vibrate, this is now part of the notifier object.
+ */
+ Vibrate *vibration = [[Vibrate alloc] init];
+ [vibration vibrate];
+ [vibration release];
+
+ } else if([command isEqualToString:@"openmap"]) {
+
+ NSString *mapurl = [@"maps:" stringByAppendingString:options];
+
+ [[UIApplication sharedApplication] openURL:[NSURL URLWithString:mapurl]];
+
+ } else if([command isEqualToString:@"getphoto"]){
+
+// // added/modified by urbian.org - g.mueller @urbian.org
+//
+// NSUInteger imageSource;
+//
+// //set upload url
+// photoUploadUrl = [parts objectAtIndex:3];
+// [photoUploadUrl retain];
+//
+// NSLog([@"photo-url: " stringByAppendingString:photoUploadUrl]);
+//
+// //which image source
+// if([(NSString *)[parts objectAtIndex:2] isEqualToString:@"fromCamera"]){
+// imageSource = UIImagePickerControllerSourceTypeCamera;
+// } else if([(NSString *)[parts objectAtIndex:2] isEqualToString:@"fromLibrary"]){
+// imageSource = UIImagePickerControllerSourceTypePhotoLibrary;
+// } else {
+// NSLog(@"photo: no Source type set");
+// return NO;
+// }
+//
+// //check if source is available
+// if([UIImagePickerController isSourceTypeAvailable:imageSource])
+// {
+// picker = [[UIImagePickerController alloc]init];
+// picker.sourceType = imageSource;
+// picker.allowsImageEditing = YES;
+// picker.delegate = self;
+//
+// [viewController presentModalViewController:picker animated:YES];
+//
+// } else {
+// NSLog(@"photo: source not available!");
+// return NO;
+// }
+//
+// webView.hidden = YES;
+
+ NSLog(@"photo dialog open now!");
+ } else if([command isEqualToString:@"getContacts"]) {
+
+ contacts = [[Contacts alloc] init];
+ jsCallBack = [contacts getContacts];
+ NSLog(@"%@",jsCallBack);
+ [theWebView stringByEvaluatingJavaScriptFromString:jsCallBack];
+
+ [contacts release];
+
+ } else if ([command isEqualToString:@"playSound"]) {
+
+ NSBundle * mainBundle = [NSBundle mainBundle];
+ NSArray *soundFile = [options componentsSeparatedByString:@"."];
+
+ NSString *file = (NSString *)[soundFile objectAtIndex:0];
+ NSString *ext = (NSString *)[soundFile objectAtIndex:1];
+ NSLog(file);
+ sound = [[Sound alloc] initWithContentsOfFile:[mainBundle pathForResource:file ofType:ext]];
+ [sound play];
+ }
+
+
+ return NO;
+ } else {
+
+ /*
+ * We don't have a PhoneGap request, it could be file or something else
+ */
+ if (range.location == NSNotFound) {
+ [[UIApplication sharedApplication] openURL:url];
+ }
+ }
+
+ return YES;
+}
+
+
+
+/*
+ * accelerometer - Sends Accel Data back to the Device.
+ */
+- (void) accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
+ NSString * jsCallBack = nil;
+ jsCallBack = [[NSString alloc] initWithFormat:@"var _accel={x:%f,y:%f,z:%f};", acceleration.x, acceleration.y, acceleration.z];
+ [webView stringByEvaluatingJavaScriptFromString:jsCallBack];
+}
+
+
+// TODO Move to Image.m
+/*
+- (void)imagePickerController:(UIImagePickerController *)thePicker didFinishPickingImage:(UIImage *)theImage editingInfo:(NSDictionary *)editingInfo
+{
+
+ //modified by urbian.org - g.mueller @urbian.org
+
+ NSLog(@"photo: picked image");
+
+ NSData * imageData = UIImageJPEGRepresentation(theImage, 0.75);
+
+ NSString *urlString = [@"http://" stringByAppendingString:photoUploadUrl]; // upload the photo to this url
+
+ NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
+ [request setURL:[NSURL URLWithString:urlString]];
+ [request setHTTPMethod:@"POST"];
+
+ // ---------
+ //Add the header info
+ NSString *stringBoundary = [NSString stringWithString:@"0xKhTmLbOuNdArY"];
+ NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",stringBoundary];
+ [request addValue:contentType forHTTPHeaderField: @"Content-Type"];
+
+ //create the body
+ NSMutableData *postBody = [NSMutableData data];
+ [postBody appendData:[[NSString stringWithFormat:@"--%@\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
+
+ //add data field and file data
+ [postBody appendData:[[NSString stringWithString:@"Content-Disposition: form-data; name=\"photo_0\"; filename=\"photo\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
+ [postBody appendData:[[NSString stringWithString:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
+
+ [postBody appendData:[NSData dataWithData:imageData]];
+ [postBody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
+
+ // ---------
+ [request setHTTPBody:postBody];
+
+ //NSURLConnection *
+ conn=[[NSURLConnection alloc] initWithRequest:request delegate:self];
+
+ if(conn) {
+ receivedData=[[NSMutableData data] retain];
+ NSString *sourceSt = [[NSString alloc] initWithBytes:[receivedData bytes] length:[receivedData length] encoding:NSUTF8StringEncoding];
+ NSLog([@"photo: connection sucess" stringByAppendingString:sourceSt]);
+
+ } else {
+ NSLog(@"photo: upload failed!");
+ }
+
+ [[thePicker parentViewController] dismissModalViewControllerAnimated:YES];
+
+ webView.hidden = NO;
+ [window bringSubviewToFront:webView];
+
+}
+
+
+// TODO Move to Image.m
+- (void)imagePickerControllerDidCancel:(UIImagePickerController *)thePicker
+{
+ // Dismiss the image selection and close the program
+ [[thePicker parentViewController] dismissModalViewControllerAnimated:YES];
+
+ //added by urbian - the webapp should know when the user canceled
+ NSString * jsCallBack = nil;
+
+ jsCallBack = [[NSString alloc] initWithFormat:@"gotPhoto('CANCEL');", lastUploadedPhoto];
+ [webView stringByEvaluatingJavaScriptFromString:jsCallBack];
+ [jsCallBack release];
+
+ // Hide the imagePicker and bring the web page back into focus
+ NSLog(@"Photo Cancel Request");
+ webView.hidden = NO;
+ [window bringSubviewToFront:webView];
+}
+
+
+// TODO Move to Image.m
+- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
+
+ NSLog(@"photo: upload finished!");
+
+ //added by urbian.org - g.mueller
+ NSString *aStr = [[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding];
+
+ //upload.php should return "filename=<filename>"
+ NSLog(aStr);
+ NSArray * parts = [aStr componentsSeparatedByString:@"="];
+ //set filename
+ lastUploadedPhoto = (NSString *)[parts objectAtIndex:1];
+
+ //now the callback: return lastUploadedPhoto
+
+ NSString * jsCallBack = nil;
+
+ if(lastUploadedPhoto == nil) lastUploadedPhoto = @"ERROR";
+
+ jsCallBack = [[NSString alloc] initWithFormat:@"gotPhoto('%@');", lastUploadedPhoto];
+
+ [webView stringByEvaluatingJavaScriptFromString:jsCallBack];
+
+ NSLog(@"Succeeded! Received %d bytes of data",[receivedData length]);
+ NSLog(jsCallBack);
+
+ // release the connection, and the data object
+ [conn release];
+ [receivedData release];
+
+#if TARGET_IPHONE_SIMULATOR
+ alert(@"Did finish loading image!");
+#endif
+}
+
+
+// TODO Move to Image.m
+-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *) response {
+
+ //added by urbian.org
+ NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
+ NSLog(@"HTTP Status Code: %i", [httpResponse statusCode]);
+
+ [receivedData setLength:0];
+}
+
+- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
+{
+ // append the new data to the receivedData
+ // receivedData is declared as a method instance elsewhere
+ [receivedData appendData:data];
+ NSLog(@"photo: progress");
+}
+
+
+// TODO Move to Image.m
+- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
+ NSLog([@"photo: upload failed! " stringByAppendingString:[error description]]);
+
+#if TARGET_IPHONE_SIMULATOR
+ alert(@"Error while uploading image!");
+#endif
+}
+*/
+- (void)dealloc {
+ [appURL release];
+ [imageView release];
+ [viewController release];
+ [window release];
+ [imagePickerController release];
+ [appURL release];
+ [sound release];
+ [super dealloc];
+}
+
+
+@end
20 Classes/PhoneGapViewController.h
@@ -0,0 +1,20 @@
+//
+// PhoneGapViewController.h
+// PhoneGap
+//
+// Created by Nitobi on 15/12/08.
+// Copyright 2008 Nitobi. All rights reserved.
+//
+
+
+#import <UIKit/UIKit.h>
+#import <Foundation/Foundation.h>
+
+@interface PhoneGapViewController : UIViewController {
+ IBOutlet UIWebView *webView;
+}
+
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation;
+- (void)willRotateToInterfaceOrientation: (UIInterfaceOrientation)toInterfaceOrientation duration: (NSTimeInterval)duration;
+
+@end
48 Classes/PhoneGapViewController.m
@@ -0,0 +1,48 @@
+//
+// PhoneGapViewController.m
+// PhoneGap
+//
+// Created by Nitobi on 15/12/08.
+// Copyright 2008 Nitobi. All rights reserved.
+//
+
+#import "PhoneGapViewController.h"
+#import "PhoneGapDelegate.h"
+
+@implementation PhoneGapViewController
+
+
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation
+{
+ return NO;
+}
+
+
+- (void)willRotateToInterfaceOrientation: (UIInterfaceOrientation)toInterfaceOrientation duration: (NSTimeInterval)duration {
+ NSString * jsCallBack = nil;
+ NSLog(@"IN Rotate");
+ double i = 0;
+
+ switch (toInterfaceOrientation){
+ case UIInterfaceOrientationPortrait:
+ i = 0;
+ break;
+ case UIInterfaceOrientationPortraitUpsideDown:
+ i = 180;
+ break;
+ case UIInterfaceOrientationLandscapeLeft:
+ i = 90;
+ break;
+ case UIInterfaceOrientationLandscapeRight:
+ i = -90;
+ break;
+ }
+
+ jsCallBack = [[NSString alloc] initWithFormat:@"var _orientation=%f;", i];
+ [webView stringByEvaluatingJavaScriptFromString:jsCallBack];
+
+ [jsCallBack release];
+
+}
+
+@end
19 Classes/Sound.h
@@ -0,0 +1,19 @@
+/*
+ * Sound.h
+ *
+ * Created by Nitobi on 12/12/08.
+ * Copyright 2008 Nitobi. All rights reserved.
+ *
+ */
+
+#import <Foundation/Foundation.h>
+#import <AudioToolbox/AudioServices.h>
+
+@interface Sound : NSObject {
+ SystemSoundID soundID;
+}
+
+- (id) initWithContentsOfFile:(NSString * )path;
+- (void) play;
+
+@end
34 Classes/Sound.m
@@ -0,0 +1,34 @@
+/*
+ * Sound.m
+ *
+ * Created by Nitobi on 12/12/08.
+ * Copyright 2008 Nitobi. All rights reserved.
+ *
+ */
+
+#import "Sound.h"
+
+
+@implementation Sound
+
+- (id) initWithContentsOfFile:(NSString *)path
+{
+ self = [super init];
+ if (self != nil) {
+ NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO];
+ AudioServicesCreateSystemSoundID((CFURLRef)filePath, &soundID);
+ }
+ return self;
+}
+
+/*
+ * play - Plays the sound
+ */
+- (void) play {
+ AudioServicesPlaySystemSound(soundID);
+}
+
+- (void) dealloc {
+ [super dealloc];
+}
+@end
17 Classes/Vibrate.h
@@ -0,0 +1,17 @@
+/*
+ * Vibrate.h
+ *
+ * Created by Nitobi on 12/12/08.
+ * Copyright 2008 Nitobi. All rights reserved.
+ *
+ */
+
+#import <UIKit/UIKit.h>
+#import <AudioToolbox/AudioServices.h>
+
+@interface Vibrate : NSObject {
+}
+
+- (void)vibrate;
+
+@end
26 Classes/Vibrate.m
@@ -0,0 +1,26 @@
+/*
+ * Vibrate.m
+ *
+ * Created by Nitobi on 12/12/08.
+ * Copyright 2008 Nitobi. All rights reserved.
+ *
+ */
+
+#import "Vibrate.h"
+
+
+@implementation Vibrate
+
+- (id)init{
+ return self;
+}
+
+- (void)vibrate{
+ AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
+}
+
+- (void)dealloc {
+ [super dealloc];
+}
+
+@end
BIN  Default.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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>en</string>
+ <key>CFBundleDisplayName</key>
+ <string>Pigeon</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIconFile</key>
+ <string>icon.png</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.sintaxi.tel</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.0.1</string>
+ <key>LSRequiresIPhoneOS</key>
+ <true/>
+ <key>NSMainNibFile</key>
+ <string>MainWindow</string>
+</dict>
+</plist>
324 MainWindow.xib
@@ -0,0 +1,324 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.03">
+ <data>
+ <int key="IBDocument.SystemTarget">512</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="427554174">
+ <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"/>
+ <bool key="IBUIVisibleAtLaunch">YES</bool>
+ </object>
+ <object class="IBUIViewController" id="943309135">
+ <object class="IBUIView" key="IBUIView" id="197095679">
+ <nil key="NSNextResponder"/>
+ <int key="NSvFlags">274</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBUIWebView" id="586399405">
+ <reference key="NSNextResponder" ref="197095679"/>
+ <int key="NSvFlags">274</int>
+ <string key="NSFrameSize">{320, 480}</string>
+ <reference key="NSSuperview" ref="197095679"/>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MSAwLjUgMAA</bytes>
+ </object>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <bool key="IBUIMultipleTouchEnabled">YES</bool>
+ </object>
+ </object>
+ <string key="NSFrameSize">{320, 480}</string>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MC4wNDQzNTc5NzggMC4wNDQzNTc5NzggMC4wNDQzNTc5NzgAA</bytes>
+ </object>
+ <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+ </object>
+ </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">window</string>
+ <reference key="source" ref="664661524"/>
+ <reference key="destination" ref="380026005"/>
+ </object>
+ <int key="connectionID">5</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">viewController</string>
+ <reference key="source" ref="664661524"/>
+ <reference key="destination" ref="943309135"/>
+ </object>
+ <int key="connectionID">11</int>
+ </object>
+ <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">19</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">webView</string>
+ <reference key="source" ref="664661524"/>
+ <reference key="destination" ref="586399405"/>
+ </object>
+ <int key="connectionID">20</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"/>
+ <string key="objectName">Phone Gap App Delegate</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="427554174"/>
+ <reference key="parent" ref="957960031"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">10</int>
+ <reference key="object" ref="943309135"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="197095679"/>
+ </object>
+ <reference key="parent" ref="957960031"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">12</int>
+ <reference key="object" ref="197095679"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="586399405"/>
+ </object>
+ <reference key="parent" ref="943309135"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">13</int>
+ <reference key="object" ref="586399405"/>
+ <reference key="parent" ref="197095679"/>
+ <string key="objectName">My WebView</string>
+ </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>10.CustomClassName</string>
+ <string>10.IBEditorWindowLastContentRect</string>
+ <string>10.IBPluginDependency</string>
+ <string>12.IBPluginDependency</string>
+ <string>13.IBPluginDependency</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>
+ <string>PhoneGapViewController</string>
+ <string>{{23, 161}, {320, 480}}</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</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>{{439, 171}, {320, 480}}</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>PhoneGapDelegate</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">28</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <object class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">PhoneGapDelegate</string>
+ <string key="superclassName">NSObject</string>
+ <object class="NSMutableDictionary" key="outlets">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSMutableArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>activityView</string>
+ <string>imageView</string>
+ <string>viewController</string>
+ <string>webView</string>
+ <string>window</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>UIActivityIndicatorView</string>
+ <string>UIImageView</string>
+ <string>PhoneGapViewController</string>
+ <string>UIWebView</string>
+ <string>UIWindow</string>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/PhoneGapDelegate.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">PhoneGapDelegate</string>
+ <string key="superclassName">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBUserSource</string>
+ <string key="minorKey"/>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">PhoneGapViewController</string>
+ <string key="superclassName">UIViewController</string>
+ <object class="NSMutableDictionary" key="outlets">
+ <string key="NS.key.0">webView</string>
+ <string key="NS.object.0">UIWebView</string>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/PhoneGapViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">PhoneGapViewController</string>
+ <string key="superclassName">UIViewController</string>
+ <object class="NSMutableDictionary" key="actions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSMutableArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>loadView</string>
+ <string>pushBack</string>
+ <string>pushHome</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>id</string>
+ <string>id</string>
+ <string>id</string>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBUserSource</string>
+ <string key="minorKey"/>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIActivityIndicatorView</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBUserSource</string>
+ <string key="minorKey"/>
+ </object>
+ </object>
+ </object>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.LastKnownRelativeProjectPath">PhoneGap.xcodeproj</string>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ </data>
+</archive>
8 PhoneGap_Prefix.pch
@@ -0,0 +1,8 @@
+//
+// Prefix header for all source files of the 'Glass' target in the 'Glass' project
+//
+
+#ifdef __OBJC__
+#import <Foundation/Foundation.h>
+#import <UIKit/UIKit.h>
+#endif
1,413 Pigeon.xcodeproj/andrewlunny.mode1v3
@@ -0,0 +1,1413 @@
+<?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>ActivePerspectiveName</key>
+ <string>Project</string>
+ <key>AllowedModules</key>
+ <array>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Name</key>
+ <string>Groups and Files Outline View</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Name</key>
+ <string>Editor</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCTaskListModule</string>
+ <key>Name</key>
+ <string>Task List</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCDetailModule</string>
+ <key>Name</key>
+ <string>File and Smart Group Detail Viewer</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXBuildResultsModule</string>
+ <key>Name</key>
+ <string>Detailed Build Results Viewer</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXProjectFindModule</string>
+ <key>Name</key>
+ <string>Project Batch Find Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCProjectFormatConflictsModule</string>
+ <key>Name</key>
+ <string>Project Format Conflicts List</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXBookmarksModule</string>
+ <key>Name</key>
+ <string>Bookmarks Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXClassBrowserModule</string>
+ <key>Name</key>
+ <string>Class Browser</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXCVSModule</string>
+ <key>Name</key>
+ <string>Source Code Control Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXDebugBreakpointsModule</string>
+ <key>Name</key>
+ <string>Debug Breakpoints Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCDockableInspector</string>
+ <key>Name</key>
+ <string>Inspector</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXOpenQuicklyModule</string>
+ <key>Name</key>
+ <string>Open Quickly Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXDebugSessionModule</string>
+ <key>Name</key>
+ <string>Debugger</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXDebugCLIModule</string>
+ <key>Name</key>
+ <string>Debug Console</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCSnapshotModule</string>
+ <key>Name</key>
+ <string>Snapshots Tool</string>
+ </dict>
+ </array>
+ <key>BundlePath</key>
+ <string>/Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources</string>
+ <key>Description</key>
+ <string>DefaultDescriptionKey</string>
+ <key>DockingSystemVisible</key>
+ <false/>
+ <key>Extension</key>
+ <string>mode1v3</string>
+ <key>FavBarConfig</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>E710190C0FE95EA4003D342F</string>
+ <key>XCBarModuleItemNames</key>
+ <dict/>
+ <key>XCBarModuleItems</key>
+ <array/>
+ </dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>com.apple.perspectives.project.mode1v3</string>
+ <key>MajorVersion</key>
+ <integer>33</integer>
+ <key>MinorVersion</key>
+ <integer>0</integer>
+ <key>Name</key>
+ <string>Default</string>
+ <key>Notifications</key>
+ <array/>
+ <key>OpenEditors</key>
+ <array/>
+ <key>PerspectiveWidths</key>
+ <array>
+ <integer>-1</integer>
+ <integer>-1</integer>
+ </array>
+ <key>Perspectives</key>
+ <array>
+ <dict>
+ <key>ChosenToolbarItems</key>
+ <array>
+ <string>active-combo-popup</string>
+ <string>action</string>
+ <string>NSToolbarFlexibleSpaceItem</string>
+ <string>build-and-go</string>
+ <string>com.apple.ide.PBXToolbarStopButton</string>
+ <string>get-info</string>
+ <string>NSToolbarFlexibleSpaceItem</string>
+ <string>com.apple.pbx.toolbar.searchfield</string>
+ </array>
+ <key>ControllerClassBaseName</key>
+ <string></string>
+ <key>IconName</key>
+ <string>WindowOfProjectWithEditor</string>
+ <key>Identifier</key>
+ <string>perspective.project</string>
+ <key>IsVertical</key>
+ <false/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <true/>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXBottomSmartGroupGIDs</key>
+ <array>
+ <string>1C37FBAC04509CD000000102</string>
+ <string>1C37FAAC04509CD000000102</string>
+ <string>1C08E77C0454961000C914BD</string>
+ <string>1C37FABC05509CD000000102</string>
+ <string>1C37FABC05539CD112110102</string>
+ <string>E2644B35053B69B200211256</string>
+ <string>1C37FABC04509CD000100104</string>
+ <string>1CC0EA4004350EF90044410B</string>
+ <string>1CC0EA4004350EF90041110B</string>
+ </array>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Files</string>
+ <key>PBXProjectStructureProvided</key>
+ <string>yes</string>
+ <key>PBXSmartGroupTreeModuleColumnData</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+ <array>
+ <real>186</real>
+ </array>
+ <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+ <array>
+ <string>MainColumn</string>
+ </array>
+ </dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+ <array>
+ <string>29B97314FDCFA39411CA2CEA</string>
+ <string>AA13D33F0F202D0400B18061</string>
+ <string>E7D5E4401003FA91005B1662</string>
+ <string>AA13D3080F20286200B18061</string>
+ <string>29B97317FDCFA39411CA2CEA</string>
+ <string>1C37FABC05509CD000000102</string>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+ <array>
+ <array>
+ <integer>2</integer>
+ <integer>1</integer>
+ <integer>0</integer>
+ </array>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+ <string>{{0, 0}, {186, 660}}</string>
+ </dict>
+ <key>PBXTopSmartGroupGIDs</key>
+ <array/>
+ <key>XCIncludePerspectivesSwitch</key>
+ <true/>
+ <key>XCSharingToken</key>
+ <string>com.apple.Xcode.GFSharingToken</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {203, 678}}</string>
+ <key>GroupTreeTableConfiguration</key>
+ <array>
+ <string>MainColumn</string>
+ <real>186</real>
+ </array>
+ <key>RubberWindowFrame</key>
+ <string>-1154 270 1046 719 -1280 0 1280 1024 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Proportion</key>
+ <string>203pt</string>
+ </dict>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B20306471E060097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>pigeon.js</string>
+ <key>PBXSplitModuleInNavigatorKey</key>
+ <dict>
+ <key>Split0</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B20406471E060097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>pigeon.js</string>
+ <key>_historyCapacity</key>
+ <integer>0</integer>
+ <key>bookmark</key>
+ <string>E7D5E4F7100EA373005B1662</string>
+ <key>history</key>
+ <array>
+ <string>E71019770FEAF7D7003D342F</string>
+ <string>E72F0F650FF422C800CBB1C1</string>
+ <string>E72F0FB90FF4248C00CBB1C1</string>
+ <string>E7EE383C0FF4263100561E0F</string>
+ <string>E77069560FF5976200333115</string>
+ <string>E7D5E48B100D292F005B1662</string>
+ <string>E7D5E4F1100E9C03005B1662</string>
+ <string>E7D5E48C100D292F005B1662</string>
+ </array>
+ <key>prevStack</key>
+ <array>
+ <string>E710197E0FEAF7D7003D342F</string>
+ <string>E710197F0FEAF7D7003D342F</string>
+ <string>E71019810FEAF7D7003D342F</string>
+ <string>E72F0FBC0FF4248C00CBB1C1</string>
+ <string>E7EE38400FF4263100561E0F</string>
+ <string>E77067E90FF4499E00333115</string>
+ <string>E77068350FF5674300333115</string>
+ <string>E77068630FF585BB00333115</string>
+ <string>E7D5E47510055367005B1662</string>
+ <string>E7D5E48D100D292F005B1662</string>
+ <string>E7D5E48E100D292F005B1662</string>
+ <string>E7D5E4F2100E9C03005B1662</string>
+ </array>
+ </dict>
+ <key>SplitCount</key>
+ <string>1</string>
+ </dict>
+ <key>StatusBarVisibility</key>
+ <true/>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {838, 571}}</string>
+ <key>RubberWindowFrame</key>
+ <string>-1154 270 1046 719 -1280 0 1280 1024 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>571pt</string>
+ </dict>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B20506471E060097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Detail</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 576}, {838, 102}}</string>
+ <key>RubberWindowFrame</key>
+ <string>-1154 270 1046 719 -1280 0 1280 1024 </string>
+ </dict>
+ <key>Module</key>
+ <string>XCDetailModule</string>
+ <key>Proportion</key>
+ <string>102pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>838pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Project</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>XCModuleDock</string>
+ <string>PBXSmartGroupTreeModule</string>
+ <string>XCModuleDock</string>
+ <string>PBXNavigatorGroup</string>
+ <string>XCDetailModule</string>
+ </array>
+ <key>TableOfContents</key>
+ <array>
+ <string>E7D5E44C1003FA9B005B1662</string>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <string>E7D5E44D1003FA9B005B1662</string>
+ <string>1CE0B20306471E060097A5F4</string>
+ <string>1CE0B20506471E060097A5F4</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.defaultV3</string>
+ </dict>
+ <dict>
+ <key>ControllerClassBaseName</key>
+ <string></string>
+ <key>IconName</key>
+ <string>WindowOfProject</string>
+ <key>Identifier</key>
+ <string>perspective.morph</string>
+ <key>IsVertical</key>
+ <integer>0</integer>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXBottomSmartGroupGIDs</key>
+ <array>
+ <string>1C37FBAC04509CD000000102</string>
+ <string>1C37FAAC04509CD000000102</string>
+ <string>1C08E77C0454961000C914BD</string>
+ <string>1C37FABC05509CD000000102</string>
+ <string>1C37FABC05539CD112110102</string>
+ <string>E2644B35053B69B200211256</string>
+ <string>1C37FABC04509CD000100104</string>
+ <string>1CC0EA4004350EF90044410B</string>
+ <string>1CC0EA4004350EF90041110B</string>
+ </array>
+ <key>PBXProjectModuleGUID</key>
+ <string>11E0B1FE06471DED0097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Files</string>
+ <key>PBXProjectStructureProvided</key>
+ <string>yes</string>
+ <key>PBXSmartGroupTreeModuleColumnData</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+ <array>
+ <real>186</real>
+ </array>
+ <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+ <array>
+ <string>MainColumn</string>
+ </array>
+ </dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+ <array>
+ <string>29B97314FDCFA39411CA2CEA</string>
+ <string>1C37FABC05509CD000000102</string>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+ <array>
+ <array>
+ <integer>0</integer>
+ </array>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+ <string>{{0, 0}, {186, 337}}</string>
+ </dict>
+ <key>PBXTopSmartGroupGIDs</key>
+ <array/>
+ <key>XCIncludePerspectivesSwitch</key>
+ <integer>1</integer>
+ <key>XCSharingToken</key>
+ <string>com.apple.Xcode.GFSharingToken</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {203, 355}}</string>
+ <key>GroupTreeTableConfiguration</key>
+ <array>
+ <string>MainColumn</string>
+ <real>186</real>
+ </array>
+ <key>RubberWindowFrame</key>
+ <string>373 269 690 397 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Morph</string>
+ <key>PreferredWidth</key>
+ <integer>300</integer>
+ <key>ServiceClasses</key>
+ <array>
+ <string>XCModuleDock</string>
+ <string>PBXSmartGroupTreeModule</string>
+ </array>
+ <key>TableOfContents</key>
+ <array>
+ <string>11E0B1FE06471DED0097A5F4</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.default.shortV3</string>
+ </dict>
+ </array>
+ <key>PerspectivesBarVisible</key>
+ <false/>
+ <key>ShelfIsVisible</key>
+ <false/>
+ <key>SourceDescription</key>
+ <string>file at '/Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources/XCPerspectivesSpecificationMode1.xcperspec'</string>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>TimeStamp</key>
+ <real>0.0</real>
+ <key>ToolbarDisplayMode</key>
+ <integer>1</integer>
+ <key>ToolbarIsVisible</key>
+ <true/>
+ <key>ToolbarSizeMode</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Perspectives</string>
+ <key>UpdateMessage</key>
+ <string>The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'?</string>
+ <key>WindowJustification</key>
+ <integer>5</integer>
+ <key>WindowOrderList</key>
+ <array>
+ <string>1C78EAAD065D492600B07095</string>
+ <string>1CD10A99069EF8BA00B06720</string>
+ <string>E710191D0FE961D6003D342F</string>
+ <string>/Users/andrewlunny/Documents/Nitobi/pigeon/Pigeon.xcodeproj</string>
+ </array>
+ <key>WindowString</key>
+ <string>-1154 270 1046 719 -1280 0 1280 1024 </string>
+ <key>WindowToolsV3</key>
+ <array>
+ <dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>windowTool.build</string>
+ <key>IsVertical</key>
+ <true/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CD0528F0623707200166675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string></string>
+ <key>StatusBarVisibility</key>
+ <true/>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {500, 218}}</string>
+ <key>RubberWindowFrame</key>
+ <string>36 250 500 500 0 0 1280 778 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>218pt</string>
+ </dict>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>XCMainBuildResultsModuleGUID</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Build</string>
+ <key>XCBuildResultsTrigger_Collapse</key>
+ <integer>1021</integer>
+ <key>XCBuildResultsTrigger_Open</key>
+ <integer>1011</integer>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 223}, {500, 236}}</string>
+ <key>RubberWindowFrame</key>
+ <string>36 250 500 500 0 0 1280 778 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXBuildResultsModule</string>
+ <key>Proportion</key>
+ <string>236pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>459pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Build Results</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXBuildResultsModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>TableOfContents</key>
+ <array>
+ <string>E710191D0FE961D6003D342F</string>
+ <string>E7D5E45010054C9D005B1662</string>
+ <string>1CD0528F0623707200166675</string>
+ <string>XCMainBuildResultsModuleGUID</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.buildV3</string>
+ <key>WindowString</key>
+ <string>36 250 500 500 0 0 1280 778 </string>
+ <key>WindowToolGUID</key>
+ <string>E710191D0FE961D6003D342F</string>
+ <key>WindowToolIsVisible</key>
+ <false/>
+ </dict>
+ <dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>windowTool.debugger</string>
+ <key>IsVertical</key>
+ <true/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>Debugger</key>
+ <dict>
+ <key>HorizontalSplitView</key>
+ <dict>
+ <key>_collapsingFrameDimension</key>
+ <real>0.0</real>
+ <key>_indexOfCollapsedView</key>
+ <integer>0</integer>
+ <key>_percentageOfCollapsedView</key>
+ <real>0.0</real>
+ <key>isCollapsed</key>
+ <string>yes</string>
+ <key>sizes</key>
+ <array>
+ <string>{{0, 0}, {316, 203}}</string>
+ <string>{{316, 0}, {378, 203}}</string>
+ </array>
+ </dict>
+ <key>VerticalSplitView</key>
+ <dict>
+ <key>_collapsingFrameDimension</key>
+ <real>0.0</real>
+ <key>_indexOfCollapsedView</key>
+ <integer>0</integer>
+ <key>_percentageOfCollapsedView</key>
+ <real>0.0</real>
+ <key>isCollapsed</key>
+ <string>yes</string>
+ <key>sizes</key>
+ <array>
+ <string>{{0, 0}, {694, 203}}</string>
+ <string>{{0, 203}, {694, 178}}</string>
+ </array>
+ </dict>
+ </dict>
+ <key>LauncherConfigVersion</key>
+ <string>8</string>
+ <key>PBXProjectModuleGUID</key>
+ <string>1C162984064C10D400B95A72</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Debug - GLUTExamples (Underwater)</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>DebugConsoleVisible</key>
+ <string>None</string>
+ <key>DebugConsoleWindowFrame</key>
+ <string>{{200, 200}, {500, 300}}</string>
+ <key>DebugSTDIOWindowFrame</key>
+ <string>{{200, 200}, {500, 300}}</string>
+ <key>Frame</key>
+ <string>{{0, 0}, {694, 381}}</string>
+ <key>PBXDebugSessionStackFrameViewKey</key>
+ <dict>
+ <key>DebugVariablesTableConfiguration</key>
+ <array>
+ <string>Name</string>
+ <real>120</real>
+ <string>Value</string>
+ <real>85</real>
+ <string>Summary</string>
+ <real>148</real>
+ </array>
+ <key>Frame</key>
+ <string>{{316, 0}, {378, 203}}</string>
+ <key>RubberWindowFrame</key>
+ <string>36 328 694 422 0 0 1280 778 </string>
+ </dict>
+ <key>RubberWindowFrame</key>
+ <string>36 328 694 422 0 0 1280 778 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXDebugSessionModule</string>
+ <key>Proportion</key>
+ <string>381pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>381pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Debugger</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXDebugSessionModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>TableOfContents</key>
+ <array>
+ <string>1CD10A99069EF8BA00B06720</string>
+ <string>E7D5E45110054C9D005B1662</string>
+ <string>1C162984064C10D400B95A72</string>
+ <string>E7D5E45210054C9D005B1662</string>
+ <string>E7D5E45310054C9D005B1662</string>
+ <string>E7D5E45410054C9D005B1662</string>
+ <string>E7D5E45510054C9D005B1662</string>
+ <string>E7D5E45610054C9D005B1662</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.debugV3</string>
+ <key>WindowString</key>
+ <string>36 328 694 422 0 0 1280 778 </string>
+ <key>WindowToolGUID</key>
+ <string>1CD10A99069EF8BA00B06720</string>
+ <key>WindowToolIsVisible</key>
+ <false/>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.find</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CDD528C0622207200134675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>&lt;No Editor&gt;</string>
+ <key>PBXSplitModuleInNavigatorKey</key>
+ <dict>
+ <key>Split0</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CD0528D0623707200166675</string>
+ </dict>