Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

initial commit for iGitHub

  • Loading branch information...
commit 6929d8426892d5bf76eed1f1b3b7d509e2c6d80d 0 parents
@schacon authored
Showing with 3,536 additions and 0 deletions.
  1. BIN  .DS_Store
  2. +68 −0 AppController.h
  3. +286 −0 AppController.m
  4. BIN  Default.png
  5. +24 −0 Info.plist
  6. +96 −0 Networking/BrowserViewController.h
  7. +404 −0 Networking/BrowserViewController.m
  8. +54 −0 Networking/TCPServer.h
  9. +236 −0 Networking/TCPServer.m
  10. +27 −0 Picker.h
  11. +117 −0 Picker.m
  12. +51 −0 Prefix.pch
  13. +72 −0 ReadMe.txt
  14. +60 −0 TapView.h
  15. +77 −0 TapView.m
  16. BIN  bg.png
  17. +23 −0 build/Debug-iphonesimulator/WiTap.app.dSYM/Contents/Info.plist
  18. BIN  build/Debug-iphonesimulator/WiTap.app.dSYM/Contents/Resources/DWARF/WiTap
  19. BIN  build/Debug-iphonesimulator/WiTap.app/Default.png
  20. +28 −0 build/Debug-iphonesimulator/WiTap.app/Info.plist
  21. +1 −0  build/Debug-iphonesimulator/WiTap.app/PkgInfo
  22. BIN  build/Debug-iphonesimulator/WiTap.app/WiTap
  23. BIN  build/Debug-iphonesimulator/WiTap.app/bg.png
  24. BIN  build/Debug-iphonesimulator/WiTap.app/icon.png
  25. +23 −0 build/Debug-iphonesimulator/iGitHub.app.dSYM/Contents/Info.plist
  26. BIN  build/Debug-iphonesimulator/iGitHub.app.dSYM/Contents/Resources/DWARF/iGitHub
  27. BIN  build/Debug-iphonesimulator/iGitHub.app/Default.png
  28. +28 −0 build/Debug-iphonesimulator/iGitHub.app/Info.plist
  29. +1 −0  build/Debug-iphonesimulator/iGitHub.app/PkgInfo
  30. BIN  build/Debug-iphonesimulator/iGitHub.app/bg.png
  31. BIN  build/Debug-iphonesimulator/iGitHub.app/iGitHub
  32. BIN  build/Debug-iphonesimulator/iGitHub.app/icon.png
  33. BIN  build/WiTap.build/Debug-iphonesimulator/WiTap.build/Objects-normal/i386/AppController.o
  34. BIN  build/WiTap.build/Debug-iphonesimulator/WiTap.build/Objects-normal/i386/BrowserViewController.o
  35. BIN  build/WiTap.build/Debug-iphonesimulator/WiTap.build/Objects-normal/i386/Picker.o
  36. BIN  build/WiTap.build/Debug-iphonesimulator/WiTap.build/Objects-normal/i386/TCPServer.o
  37. BIN  build/WiTap.build/Debug-iphonesimulator/WiTap.build/Objects-normal/i386/TapView.o
  38. +6 −0 build/WiTap.build/Debug-iphonesimulator/WiTap.build/Objects-normal/i386/WiTap.LinkFileList
  39. BIN  build/WiTap.build/Debug-iphonesimulator/WiTap.build/Objects-normal/i386/main.o
  40. BIN  build/WiTap.build/Debug-iphonesimulator/WiTap.build/WiTap-all-target-headers.hmap
  41. BIN  build/WiTap.build/Debug-iphonesimulator/WiTap.build/WiTap-generated-files.hmap
  42. BIN  build/WiTap.build/Debug-iphonesimulator/WiTap.build/WiTap-own-target-headers.hmap
  43. BIN  build/WiTap.build/Debug-iphonesimulator/WiTap.build/WiTap-project-headers.hmap
  44. BIN  build/WiTap.build/Debug-iphonesimulator/WiTap.build/WiTap.hmap
  45. BIN  build/WiTap.build/WiTap.pbxindex/categories.pbxbtree
  46. BIN  build/WiTap.build/WiTap.pbxindex/cdecls.pbxbtree
  47. BIN  build/WiTap.build/WiTap.pbxindex/decls.pbxbtree
  48. BIN  build/WiTap.build/WiTap.pbxindex/files.pbxbtree
  49. BIN  build/WiTap.build/WiTap.pbxindex/imports.pbxbtree
  50. BIN  build/WiTap.build/WiTap.pbxindex/pbxindex.header
  51. BIN  build/WiTap.build/WiTap.pbxindex/protocols.pbxbtree
  52. BIN  build/WiTap.build/WiTap.pbxindex/refs.pbxbtree
  53. BIN  build/WiTap.build/WiTap.pbxindex/strings.pbxstrings/control
  54. BIN  build/WiTap.build/WiTap.pbxindex/strings.pbxstrings/strings
  55. BIN  build/WiTap.build/WiTap.pbxindex/subclasses.pbxbtree
  56. BIN  build/WiTap.build/WiTap.pbxindex/symbols0.pbxsymbols
  57. BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/Objects-normal/i386/AppController.o
  58. BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/Objects-normal/i386/BrowserViewController.o
  59. BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/Objects-normal/i386/Picker.o
  60. BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/Objects-normal/i386/TCPServer.o
  61. BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/Objects-normal/i386/TapView.o
  62. +6 −0 build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/Objects-normal/i386/WiTap.LinkFileList
  63. +6 −0 build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/Objects-normal/i386/iGitHub.LinkFileList
  64. BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/Objects-normal/i386/main.o
  65. BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/WiTap-all-target-headers.hmap
  66. BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/WiTap-generated-files.hmap
  67. BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/WiTap-own-target-headers.hmap
  68. BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/WiTap-project-headers.hmap
  69. BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/WiTap.hmap
  70. BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/iGitHub-all-target-headers.hmap
  71. BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/iGitHub-generated-files.hmap
  72. BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/iGitHub-own-target-headers.hmap
  73. BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/iGitHub-project-headers.hmap
  74. BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/iGitHub.hmap
  75. BIN  build/iGitHub.build/iGitHub.pbxindex/categories.pbxbtree
  76. BIN  build/iGitHub.build/iGitHub.pbxindex/cdecls.pbxbtree
  77. BIN  build/iGitHub.build/iGitHub.pbxindex/decls.pbxbtree
  78. BIN  build/iGitHub.build/iGitHub.pbxindex/files.pbxbtree
  79. BIN  build/iGitHub.build/iGitHub.pbxindex/imports.pbxbtree
  80. BIN  build/iGitHub.build/iGitHub.pbxindex/pbxindex.header
  81. BIN  build/iGitHub.build/iGitHub.pbxindex/protocols.pbxbtree
  82. BIN  build/iGitHub.build/iGitHub.pbxindex/refs.pbxbtree
  83. BIN  build/iGitHub.build/iGitHub.pbxindex/strings.pbxstrings/control
  84. BIN  build/iGitHub.build/iGitHub.pbxindex/strings.pbxstrings/strings
  85. BIN  build/iGitHub.build/iGitHub.pbxindex/subclasses.pbxbtree
  86. BIN  build/iGitHub.build/iGitHub.pbxindex/symbols0.pbxsymbols
  87. +302 −0 iGitHub.xcodeproj/project.pbxproj
  88. +1,394 −0 iGitHub.xcodeproj/schacon.mode1v3
  89. +130 −0 iGitHub.xcodeproj/schacon.pbxuser
  90. BIN  icon.png
  91. +16 −0 main.m
BIN  .DS_Store
Binary file not shown
68 AppController.h
@@ -0,0 +1,68 @@
+/*
+
+File: AppController.h
+Abstract: UIApplication's delegate class, the central controller of the
+application.
+
+Version: 1.5
+
+Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc.
+("Apple") in consideration of your agreement to the following terms, and your
+use, installation, modification or redistribution of this Apple software
+constitutes acceptance of these terms. If you do not agree with these terms,
+please do not use, install, modify or redistribute this Apple software.
+
+In consideration of your agreement to abide by the following terms, and subject
+to these terms, Apple grants you a personal, non-exclusive license, under
+Apple's copyrights in this original Apple software (the "Apple Software"), to
+use, reproduce, modify and redistribute the Apple Software, with or without
+modifications, in source and/or binary forms; provided that if you redistribute
+the Apple Software in its entirety and without modifications, you must retain
+this notice and the following text and disclaimers in all such redistributions
+of the Apple Software.
+Neither the name, trademarks, service marks or logos of Apple Inc. may be used
+to endorse or promote products derived from the Apple Software without specific
+prior written permission from Apple. Except as expressly stated in this notice,
+no other rights or licenses, express or implied, are granted by Apple herein,
+including but not limited to any patent rights that may be infringed by your
+derivative works or by other works in which the Apple Software may be
+incorporated.
+
+The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR
+DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF
+CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Copyright (C) 2008 Apple Inc. All Rights Reserved.
+
+*/
+
+#import "TapView.h"
+#import "BrowserViewController.h"
+#import "Picker.h"
+#import "TCPServer.h"
+
+//CLASS INTERFACES:
+
+@interface AppController : NSObject <UIApplicationDelegate, UIActionSheetDelegate, BrowserViewControllerDelegate, TCPServerDelegate>
+{
+ UIWindow* _window;
+ Picker* _picker;
+ TCPServer* _server;
+ NSInputStream* _inStream;
+ NSOutputStream* _outStream;
+ BOOL _inReady;
+ BOOL _outReady;
+}
+- (void) activateView:(TapView*)view;
+- (void) deactivateView:(TapView*)view;
+@end
286 AppController.m
@@ -0,0 +1,286 @@
+/*
+
+File: AppController.m
+Abstract: UIApplication's delegate class, the central controller of the
+application.
+
+Version: 1.5
+
+*/
+
+#import "AppController.h"
+#import "Picker.h"
+
+//CONSTANTS:
+
+#define kNumPads 3
+
+// The Bonjour application protocol, which must:
+// 1) be no longer than 14 characters
+// 2) contain only lower-case letters, digits, and hyphens
+// 3) begin and end with lower-case letter or digit
+// It should also be descriptive and human-readable
+// See the following for more information:
+// http://developer.apple.com/networking/bonjour/faq.html
+#define kGameIdentifier @"github"
+
+
+//INTERFACES:
+
+@interface AppController ()
+- (void) setup;
+- (void) presentPicker:(NSString*)name;
+@end
+
+//CLASS IMPLEMENTATIONS:
+
+@implementation AppController
+
+- (void) _showAlert:(NSString*)title
+{
+ UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:title message:@"Check your networking configuration." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
+ [alertView show];
+ [alertView release];
+}
+
+- (void) applicationDidFinishLaunching:(UIApplication*)application
+{
+ CGRect rect;
+ UIView* view;
+ NSUInteger x,
+ y;
+
+ //Create a full-screen window
+ _window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
+ [_window setBackgroundColor:[UIColor darkGrayColor]];
+
+ //Create the tap views and add them to the view controller's view
+ rect = [[UIScreen mainScreen] applicationFrame];
+ for(y = 0; y < kNumPads; ++y) {
+ for(x = 0; x < kNumPads; ++x) {
+ view = [[TapView alloc] initWithFrame:CGRectMake(rect.origin.x + x * rect.size.width / (float)kNumPads, rect.origin.y + y * rect.size.height / (float)kNumPads, rect.size.width / (float)kNumPads, rect.size.height / (float)kNumPads)];
+ [view setMultipleTouchEnabled:NO];
+ [view setBackgroundColor:[UIColor colorWithHue:((y * kNumPads + x) / (float)(kNumPads * kNumPads)) saturation:0.75 brightness:0.75 alpha:1.0]];
+ [view setTag:(y * kNumPads + x + 1)];
+ [_window addSubview:view];
+ [view release];
+ }
+ }
+
+ //Show the window
+ [_window makeKeyAndVisible];
+
+ //Create and advertise a new game and discover other availble games
+ [self setup];
+}
+
+- (void) dealloc
+{
+ [_inStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
+ [_inStream release];
+
+ [_outStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
+ [_outStream release];
+
+ [_server release];
+
+ [_picker release];
+
+ [_window release];
+
+ [super dealloc];
+}
+
+- (void) setup {
+ [_server release];
+ _server = nil;
+
+ [_inStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
+ [_inStream release];
+ _inStream = nil;
+ _inReady = NO;
+
+ [_outStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
+ [_outStream release];
+ _outStream = nil;
+ _outReady = NO;
+
+ _server = [TCPServer new];
+ [_server setDelegate:self];
+ NSError* error;
+ if(_server == nil || ![_server start:&error]) {
+ NSLog(@"Failed creating server: %@", error);
+ [self _showAlert:@"Failed creating server"];
+ return;
+ }
+
+ //Start advertising to clients, passing nil for the name to tell Bonjour to pick use default name
+ if(![_server enableBonjourWithDomain:@"local" applicationProtocol:[TCPServer bonjourTypeFromIdentifier:kGameIdentifier] name:nil]) {
+ [self _showAlert:@"Failed advertising server"];
+ return;
+ }
+
+ [self presentPicker:nil];
+}
+
+// Make sure to let the user know what name is being used for Bonjour advertisement.
+// This way, other players can browse for and connect to this game.
+// Note that this may be called while the alert is already being displayed, as
+// Bonjour may detect a name conflict and rename dynamically.
+- (void) presentPicker:(NSString*)name {
+ if (!_picker) {
+ _picker = [[Picker alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] type:[TCPServer bonjourTypeFromIdentifier:kGameIdentifier]];
+ _picker.delegate = self;
+ }
+
+ _picker.gameName = name;
+
+ if (!_picker.superview) {
+ [_window addSubview:_picker];
+ }
+}
+
+- (void) destroyPicker {
+ [_picker removeFromSuperview];
+ [_picker release];
+ _picker = nil;
+}
+
+// If we display an error or an alert that the remote disconnected, handle dismissal and return to setup
+- (void) alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+ [self setup];
+}
+
+- (void) send:(const uint8_t)message
+{
+ if (_outStream && [_outStream hasSpaceAvailable])
+ if([_outStream write:(const uint8_t *)&message maxLength:sizeof(const uint8_t)] == -1)
+ [self _showAlert:@"Failed sending data to peer"];
+}
+
+- (void) activateView:(TapView*)view
+{
+ [self send:[view tag] | 0x80];
+}
+
+- (void) deactivateView:(TapView*)view
+{
+ [self send:[view tag] & 0x7f];
+}
+
+- (void) openStreams
+{
+ _inStream.delegate = self;
+ [_inStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
+ [_inStream open];
+ _outStream.delegate = self;
+ [_outStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
+ [_outStream open];
+}
+
+- (void) browserViewController:(BrowserViewController*)bvc didResolveInstance:(NSNetService*)netService
+{
+ if (!netService) {
+ [self setup];
+ return;
+ }
+
+ if (![netService getInputStream:&_inStream outputStream:&_outStream]) {
+ [self _showAlert:@"Failed connecting to server"];
+ return;
+ }
+
+ [self openStreams];
+}
+
+@end
+
+@implementation AppController (NSStreamDelegate)
+
+- (void) stream:(NSStream*)stream handleEvent:(NSStreamEvent)eventCode
+{
+ UIAlertView* alertView;
+ switch(eventCode) {
+ case NSStreamEventOpenCompleted:
+ {
+ [self destroyPicker];
+
+ [_server release];
+ _server = nil;
+
+ if (stream == _inStream)
+ _inReady = YES;
+ else
+ _outReady = YES;
+
+ if (_inReady && _outReady) {
+ alertView = [[UIAlertView alloc] initWithTitle:@"Game started!" message:nil delegate:nil cancelButtonTitle:nil otherButtonTitles:@"Continue", nil];
+ [alertView show];
+ [alertView release];
+ }
+ break;
+ }
+ case NSStreamEventHasBytesAvailable:
+ {
+ if (stream == _inStream) {
+ uint8_t b;
+ unsigned int len = 0;
+ len = [_inStream read:&b maxLength:sizeof(uint8_t)];
+ if(!len) {
+ if ([stream streamStatus] != NSStreamStatusAtEnd)
+ [self _showAlert:@"Failed reading data from peer"];
+ } else {
+ NSLog(@"%d", b);
+ }
+ }
+ break;
+ }
+ case NSStreamEventEndEncountered:
+ {
+ NSArray* array = [_window subviews];
+ TapView* view;
+ UIAlertView* alertView;
+
+ NSLog(@"%s", _cmd);
+
+ //Notify all tap views
+ for(view in array)
+ [view touchUp:YES];
+
+ alertView = [[UIAlertView alloc] initWithTitle:@"Peer Disconnected!" message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:@"Continue", nil];
+ [alertView show];
+ [alertView release];
+
+ break;
+ }
+ }
+}
+
+@end
+
+@implementation AppController (TCPServerDelegate)
+
+- (void) serverDidEnableBonjour:(TCPServer*)server withName:(NSString*)string
+{
+ NSLog(@"%s", _cmd);
+ [self presentPicker:string];
+}
+
+- (void)didAcceptConnectionForServer:(TCPServer*)server inputStream:(NSInputStream *)istr outputStream:(NSOutputStream *)ostr
+{
+ if (_inStream || _outStream || server != _server)
+ return;
+
+ [_server release];
+ _server = nil;
+
+ _inStream = istr;
+ [_inStream retain];
+ _outStream = ostr;
+ [_outStream retain];
+
+ [self openStreams];
+}
+
+@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.
24 Info.plist
@@ -0,0 +1,24 @@
+<?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>icon.png</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.yourcompany.${PRODUCT_NAME:identifier}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>UIRequiresPersistentWiFi</key>
+ <true/>
+</dict>
+</plist>
96 Networking/BrowserViewController.h
@@ -0,0 +1,96 @@
+/*
+
+File: BrowserViewController.h
+Abstract:
+ View controller for the service instance list.
+ This object manages a NSNetServiceBrowser configured to look for Bonjour
+services.
+ It has an array of NSNetService objects that are displayed in a table view.
+ When the service browser reports that it has discovered a service, the
+corresponding NSNetService is added to the array.
+ When a service goes away, the corresponding NSNetService is removed from the
+array.
+ Selecting an item in the table view asynchronously resolves the corresponding
+net service.
+ When that resolution completes, the delegate is called with the corresponding
+NSNetService.
+
+
+Version: 1.5
+
+Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc.
+("Apple") in consideration of your agreement to the following terms, and your
+use, installation, modification or redistribution of this Apple software
+constitutes acceptance of these terms. If you do not agree with these terms,
+please do not use, install, modify or redistribute this Apple software.
+
+In consideration of your agreement to abide by the following terms, and subject
+to these terms, Apple grants you a personal, non-exclusive license, under
+Apple's copyrights in this original Apple software (the "Apple Software"), to
+use, reproduce, modify and redistribute the Apple Software, with or without
+modifications, in source and/or binary forms; provided that if you redistribute
+the Apple Software in its entirety and without modifications, you must retain
+this notice and the following text and disclaimers in all such redistributions
+of the Apple Software.
+Neither the name, trademarks, service marks or logos of Apple Inc. may be used
+to endorse or promote products derived from the Apple Software without specific
+prior written permission from Apple. Except as expressly stated in this notice,
+no other rights or licenses, express or implied, are granted by Apple herein,
+including but not limited to any patent rights that may be infringed by your
+derivative works or by other works in which the Apple Software may be
+incorporated.
+
+The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR
+DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF
+CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Copyright (C) 2008 Apple Inc. All Rights Reserved.
+
+*/
+
+#import <UIKit/UIKit.h>
+#import <Foundation/NSNetServices.h>
+
+@class BrowserViewController;
+
+@protocol BrowserViewControllerDelegate <NSObject>
+@required
+// This method will be invoked when the user selects one of the service instances from the list.
+// The ref parameter will be the selected (already resolved) instance or nil if the user taps the 'Cancel' button (if shown).
+- (void) browserViewController:(BrowserViewController*)bvc didResolveInstance:(NSNetService*)ref;
+@end
+
+@interface BrowserViewController : UITableViewController {
+
+@private
+ id<BrowserViewControllerDelegate> _delegate;
+ NSString* _searchingForServicesString;
+ NSString* _ownName;
+ NSNetService* _ownEntry;
+ BOOL _showDisclosureIndicators;
+ NSMutableArray* _services;
+ NSNetServiceBrowser* _netServiceBrowser;
+ NSNetService* _currentResolve;
+ NSTimer* _timer;
+ BOOL _needsActivityIndicator;
+ BOOL _initialWaitOver;
+}
+
+@property (nonatomic, assign) id<BrowserViewControllerDelegate> delegate;
+@property (nonatomic, copy) NSString* searchingForServicesString;
+@property (nonatomic, copy) NSString* ownName;
+
+- (id)initWithTitle:(NSString *)title showDisclosureIndicators:(BOOL)showDisclosureIndicators showCancelButton:(BOOL)showCancelButton;
+- (BOOL)searchForServicesOfType:(NSString *)type inDomain:(NSString *)domain;
+
+@end
404 Networking/BrowserViewController.m
@@ -0,0 +1,404 @@
+/*
+
+File: BrowserViewController.m
+Abstract:
+ View controller for the service instance list.
+ This object manages a NSNetServiceBrowser configured to look for Bonjour
+services.
+ It has an array of NSNetService objects that are displayed in a table view.
+ When the service browser reports that it has discovered a service, the
+corresponding NSNetService is added to the array.
+ When a service goes away, the corresponding NSNetService is removed from the
+array.
+ Selecting an item in the table view asynchronously resolves the corresponding
+net service.
+ When that resolution completes, the delegate is called with the corresponding
+NSNetService.
+
+
+Version: 1.5
+
+Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc.
+("Apple") in consideration of your agreement to the following terms, and your
+use, installation, modification or redistribution of this Apple software
+constitutes acceptance of these terms. If you do not agree with these terms,
+please do not use, install, modify or redistribute this Apple software.
+
+In consideration of your agreement to abide by the following terms, and subject
+to these terms, Apple grants you a personal, non-exclusive license, under
+Apple's copyrights in this original Apple software (the "Apple Software"), to
+use, reproduce, modify and redistribute the Apple Software, with or without
+modifications, in source and/or binary forms; provided that if you redistribute
+the Apple Software in its entirety and without modifications, you must retain
+this notice and the following text and disclaimers in all such redistributions
+of the Apple Software.
+Neither the name, trademarks, service marks or logos of Apple Inc. may be used
+to endorse or promote products derived from the Apple Software without specific
+prior written permission from Apple. Except as expressly stated in this notice,
+no other rights or licenses, express or implied, are granted by Apple herein,
+including but not limited to any patent rights that may be infringed by your
+derivative works or by other works in which the Apple Software may be
+incorporated.
+
+The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR
+DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF
+CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Copyright (C) 2008 Apple Inc. All Rights Reserved.
+
+*/
+
+#import "BrowserViewController.h"
+
+#define kProgressIndicatorSize 20.0
+
+// A category on NSNetService that's used to sort NSNetService objects by their name.
+@interface NSNetService (BrowserViewControllerAdditions)
+- (NSComparisonResult) localizedCaseInsensitiveCompareByName:(NSNetService*)aService;
+@end
+
+@implementation NSNetService (BrowserViewControllerAdditions)
+- (NSComparisonResult) localizedCaseInsensitiveCompareByName:(NSNetService*)aService {
+ return [[self name] localizedCaseInsensitiveCompare:[aService name]];
+}
+@end
+
+
+@interface BrowserViewController()
+@property (nonatomic, retain, readwrite) NSNetService* ownEntry;
+@property (nonatomic, assign, readwrite) BOOL showDisclosureIndicators;
+@property (nonatomic, retain, readwrite) NSMutableArray* services;
+@property (nonatomic, retain, readwrite) NSNetServiceBrowser* netServiceBrowser;
+@property (nonatomic, retain, readwrite) NSNetService* currentResolve;
+@property (nonatomic, retain, readwrite) NSTimer* timer;
+@property (nonatomic, assign, readwrite) BOOL needsActivityIndicator;
+@property (nonatomic, assign, readwrite) BOOL initialWaitOver;
+
+- (void)stopCurrentResolve;
+- (void)initialWaitOver:(NSTimer*)timer;
+@end
+
+@implementation BrowserViewController
+
+@synthesize delegate = _delegate;
+@synthesize ownEntry = _ownEntry;
+@synthesize showDisclosureIndicators = _showDisclosureIndicators;
+@synthesize currentResolve = _currentResolve;
+@synthesize netServiceBrowser = _netServiceBrowser;
+@synthesize services = _services;
+@synthesize needsActivityIndicator = _needsActivityIndicator;
+@dynamic timer;
+@synthesize initialWaitOver = _initialWaitOver;
+
+
+- (id)initWithTitle:(NSString*)title showDisclosureIndicators:(BOOL)show showCancelButton:(BOOL)showCancelButton {
+
+ if ((self = [super initWithStyle:UITableViewStylePlain])) {
+ self.title = title;
+ _services = [[NSMutableArray alloc] init];
+ self.showDisclosureIndicators = show;
+
+ if (showCancelButton) {
+ // add Cancel button as the nav bar's custom right view
+ UIBarButtonItem *addButton = [[UIBarButtonItem alloc]
+ initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelAction)];
+ self.navigationItem.rightBarButtonItem = addButton;
+ [addButton release];
+ }
+
+ // Make sure we have a chance to discover devices before showing the user that nothing was found (yet)
+ [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(initialWaitOver:) userInfo:nil repeats:NO];
+ }
+
+ return self;
+}
+
+- (NSString *)searchingForServicesString {
+ return _searchingForServicesString;
+}
+
+// Holds the string that's displayed in the table view during service discovery.
+- (void)setSearchingForServicesString:(NSString *)searchingForServicesString {
+ if (_searchingForServicesString != searchingForServicesString) {
+ [_searchingForServicesString release];
+ _searchingForServicesString = [searchingForServicesString copy];
+
+ // If there are no services, reload the table to ensure that searchingForServicesString appears.
+ if ([self.services count] == 0) {
+ [self.tableView reloadData];
+ }
+ }
+}
+
+- (NSString *)ownName {
+ return _ownName;
+}
+
+// Holds the string that's displayed in the table view during service discovery.
+- (void)setOwnName:(NSString *)name {
+ if (_ownName != name) {
+ _ownName = [name copy];
+
+ if (self.ownEntry)
+ [self.services addObject:self.ownEntry];
+
+ NSNetService* service;
+
+ for (service in self.services) {
+ if ([service.name isEqual:name]) {
+ self.ownEntry = service;
+ [_services removeObject:service];
+ break;
+ }
+ }
+
+ [self.tableView reloadData];
+ }
+}
+
+// Creates an NSNetServiceBrowser that searches for services of a particular type in a particular domain.
+// If a service is currently being resolved, stop resolving it and stop the service browser from
+// discovering other services.
+- (BOOL)searchForServicesOfType:(NSString *)type inDomain:(NSString *)domain {
+
+ [self stopCurrentResolve];
+ [self.netServiceBrowser stop];
+ [self.services removeAllObjects];
+
+ NSNetServiceBrowser *aNetServiceBrowser = [[NSNetServiceBrowser alloc] init];
+ if(!aNetServiceBrowser) {
+ // The NSNetServiceBrowser couldn't be allocated and initialized.
+ return NO;
+ }
+
+ aNetServiceBrowser.delegate = self;
+ self.netServiceBrowser = aNetServiceBrowser;
+ [aNetServiceBrowser release];
+ [self.netServiceBrowser searchForServicesOfType:type inDomain:domain];
+
+ [self.tableView reloadData];
+ return YES;
+}
+
+
+- (NSTimer *)timer {
+ return _timer;
+}
+
+// When this is called, invalidate the existing timer before releasing it.
+- (void)setTimer:(NSTimer *)newTimer {
+ [_timer invalidate];
+ [newTimer retain];
+ [_timer release];
+ _timer = newTimer;
+}
+
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
+ return 1;
+}
+
+
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+ // If there are no services and searchingForServicesString is set, show one row to tell the user.
+ NSUInteger count = [self.services count];
+ if (count == 0 && self.searchingForServicesString && self.initialWaitOver)
+ return 1;
+
+ return count;
+}
+
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+
+ static NSString *tableCellIdentifier = @"UITableViewCell";
+ UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:tableCellIdentifier];
+ if (cell == nil) {
+ cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:tableCellIdentifier] autorelease];
+ }
+
+ NSUInteger count = [self.services count];
+ if (count == 0 && self.searchingForServicesString) {
+ // If there are no services and searchingForServicesString is set, show one row explaining that to the user.
+ cell.text = self.searchingForServicesString;
+ cell.textColor = [UIColor colorWithWhite:0.5 alpha:0.5];
+ cell.accessoryType = UITableViewCellAccessoryNone;
+ return cell;
+ }
+
+ // Set up the text for the cell
+ NSNetService* service = [self.services objectAtIndex:indexPath.row];
+ cell.text = [service name];
+ cell.textColor = [UIColor blackColor];
+ cell.accessoryType = self.showDisclosureIndicators ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone;
+
+ // Note that the underlying array could have changed, and we want to show the activity indicator on the correct cell
+ if (self.needsActivityIndicator && self.currentResolve == service) {
+ if (!cell.accessoryView) {
+ CGRect frame = CGRectMake(0.0, 0.0, kProgressIndicatorSize, kProgressIndicatorSize);
+ UIActivityIndicatorView* spinner = [[UIActivityIndicatorView alloc] initWithFrame:frame];
+ [spinner startAnimating];
+ spinner.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray;
+ [spinner sizeToFit];
+ spinner.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin |
+ UIViewAutoresizingFlexibleRightMargin |
+ UIViewAutoresizingFlexibleTopMargin |
+ UIViewAutoresizingFlexibleBottomMargin);
+ cell.accessoryView = spinner;
+ [spinner release];
+ }
+ } else if (cell.accessoryView) {
+ cell.accessoryView = nil;
+ }
+
+ return cell;
+}
+
+
+- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+ // Ignore the selection if there are no services.
+ if ([self.services count] == 0)
+ return nil;
+
+ return indexPath;
+}
+
+
+- (void)stopCurrentResolve {
+
+ self.needsActivityIndicator = NO;
+ self.timer = nil;
+
+ [self.currentResolve stop];
+ self.currentResolve = nil;
+}
+
+
+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+ // If another resolve was running, stop it first
+
+ [self stopCurrentResolve];
+ self.currentResolve = [self.services objectAtIndex:indexPath.row];
+
+ [self.currentResolve setDelegate:self];
+ // Attempt to resolve the service. A value of 0.0 sets an unlimited time to resolve it. The user can
+ // choose to cancel the resolve by selecting another service in the table view.
+ [self.currentResolve resolveWithTimeout:0.0];
+
+ // Make sure we give the user some feedback that the resolve is happening.
+ // We will be called back asynchronously, so we don't want the user to think
+ // we're just stuck.
+ self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(showWaiting:) userInfo:self.currentResolve repeats:NO];
+ [self.tableView reloadData];
+}
+
+// If necessary, sets up state to show an activity indicator to let the user know that a resolve is occuring.
+- (void)showWaiting:(NSTimer*)timer {
+
+ if (timer == self.timer) {
+ [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
+ NSNetService* service = (NSNetService*)[self.timer userInfo];
+ if (self.currentResolve == service) {
+ self.needsActivityIndicator = YES;
+ [self.tableView reloadData];
+ }
+ }
+}
+
+
+- (void)initialWaitOver:(NSTimer*)timer {
+ self.initialWaitOver= YES;
+ if (![self.services count])
+ [self.tableView reloadData];
+}
+
+
+- (void)sortAndUpdateUI {
+ // Sort the services by name.
+ [self.services sortUsingSelector:@selector(localizedCaseInsensitiveCompareByName:)];
+ [self.tableView reloadData];
+}
+
+
+- (void)netServiceBrowser:(NSNetServiceBrowser*)netServiceBrowser didRemoveService:(NSNetService*)service moreComing:(BOOL)moreComing {
+ // If a service went away, stop resolving it if it's currently being resolve,
+ // remove it from the list and update the table view if no more events are queued.
+
+ if (self.currentResolve && [service isEqual:self.currentResolve]) {
+ [self stopCurrentResolve];
+ }
+ [self.services removeObject:service];
+ if (self.ownEntry == service)
+ self.ownEntry = nil;
+
+ // If moreComing is NO, it means that there are no more messages in the queue from the Bonjour daemon, so we should update the UI.
+ // When moreComing is set, we don't update the UI so that it doesn't 'flash'.
+ if (!moreComing) {
+ [self sortAndUpdateUI];
+ }
+}
+
+
+- (void)netServiceBrowser:(NSNetServiceBrowser*)netServiceBrowser didFindService:(NSNetService*)service moreComing:(BOOL)moreComing {
+ // If a service came online, add it to the list and update the table view if no more events are queued.
+ if ([service.name isEqual:self.ownName])
+ self.ownEntry = service;
+ else
+ [self.services addObject:service];
+
+ // If moreComing is NO, it means that there are no more messages in the queue from the Bonjour daemon, so we should update the UI.
+ // When moreComing is set, we don't update the UI so that it doesn't 'flash'.
+ if (!moreComing) {
+ [self sortAndUpdateUI];
+ }
+}
+
+
+// This should never be called, since we resolve with a timeout of 0.0, which means indefinite
+- (void)netService:(NSNetService *)sender didNotResolve:(NSDictionary *)errorDict {
+ [self stopCurrentResolve];
+ [self.tableView reloadData];
+}
+
+
+- (void)netServiceDidResolveAddress:(NSNetService *)service {
+ assert(service == self.currentResolve);
+
+ [service retain];
+ [self stopCurrentResolve];
+
+ [self.delegate browserViewController:self didResolveInstance:service];
+ [service release];
+}
+
+
+- (void)cancelAction {
+ [self.delegate browserViewController:self didResolveInstance:nil];
+}
+
+
+- (void)dealloc {
+ // Cleanup any running resolve and free memory
+ [self stopCurrentResolve];
+ self.services = nil;
+ [self.netServiceBrowser stop];
+ self.netServiceBrowser = nil;
+ [_searchingForServicesString release];
+ [_ownName release];
+ [_ownEntry release];
+
+ [super dealloc];
+}
+
+
+@end
54 Networking/TCPServer.h
@@ -0,0 +1,54 @@
+/*
+
+File: TCPServer.h
+Abstract: A TCP server that listens on an arbitrary port.
+
+Version: 1.5
+
+*/
+
+#import <Foundation/Foundation.h>
+
+//CLASSES:
+
+@class TCPServer;
+
+//ERRORS:
+
+NSString * const TCPServerErrorDomain;
+
+typedef enum {
+ kTCPServerCouldNotBindToIPv4Address = 1,
+ kTCPServerCouldNotBindToIPv6Address = 2,
+ kTCPServerNoSocketsAvailable = 3,
+} TCPServerErrorCode;
+
+//PROTOCOLS:
+
+@protocol TCPServerDelegate <NSObject>
+@optional
+- (void) serverDidEnableBonjour:(TCPServer*)server withName:(NSString*)name;
+- (void) server:(TCPServer*)server didNotEnableBonjour:(NSDictionary *)errorDict;
+- (void) didAcceptConnectionForServer:(TCPServer*)server inputStream:(NSInputStream *)istr outputStream:(NSOutputStream *)ostr;
+@end
+
+//CLASS INTERFACES:
+
+@interface TCPServer : NSObject {
+@private
+ id _delegate;
+ uint16_t _port;
+ CFSocketRef _ipv4socket;
+ NSNetService* _netService;
+}
+
+- (BOOL)start:(NSError **)error;
+- (BOOL)stop;
+- (BOOL) enableBonjourWithDomain:(NSString*)domain applicationProtocol:(NSString*)protocol name:(NSString*)name; //Pass "nil" for the default local domain - Pass only the application protocol for "protocol" e.g. "myApp"
+- (void) disableBonjour;
+
+@property(assign) id<TCPServerDelegate> delegate;
+
++ (NSString*) bonjourTypeFromIdentifier:(NSString*)identifier;
+
+@end
236 Networking/TCPServer.m
@@ -0,0 +1,236 @@
+/*
+
+File: TCPServer.m
+Abstract: A TCP server that listens on an arbitrary port.
+
+Version: 1.5
+
+Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc.
+("Apple") in consideration of your agreement to the following terms, and your
+use, installation, modification or redistribution of this Apple software
+constitutes acceptance of these terms. If you do not agree with these terms,
+please do not use, install, modify or redistribute this Apple software.
+
+In consideration of your agreement to abide by the following terms, and subject
+to these terms, Apple grants you a personal, non-exclusive license, under
+Apple's copyrights in this original Apple software (the "Apple Software"), to
+use, reproduce, modify and redistribute the Apple Software, with or without
+modifications, in source and/or binary forms; provided that if you redistribute
+the Apple Software in its entirety and without modifications, you must retain
+this notice and the following text and disclaimers in all such redistributions
+of the Apple Software.
+Neither the name, trademarks, service marks or logos of Apple Inc. may be used
+to endorse or promote products derived from the Apple Software without specific
+prior written permission from Apple. Except as expressly stated in this notice,
+no other rights or licenses, express or implied, are granted by Apple herein,
+including but not limited to any patent rights that may be infringed by your
+derivative works or by other works in which the Apple Software may be
+incorporated.
+
+The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR
+DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF
+CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Copyright (C) 2008 Apple Inc. All Rights Reserved.
+
+*/
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <unistd.h>
+#include <CFNetwork/CFSocketStream.h>
+
+#import "TCPServer.h"
+
+NSString * const TCPServerErrorDomain = @"TCPServerErrorDomain";
+
+@interface TCPServer ()
+@property(nonatomic,retain) NSNetService* netService;
+@property(assign) uint16_t port;
+@end
+
+@implementation TCPServer
+
+@synthesize delegate=_delegate, netService=_netService, port=_port;
+
+- (id)init {
+ return self;
+}
+
+- (void)dealloc {
+ [self stop];
+ [super dealloc];
+}
+
+- (void)handleNewConnectionFromAddress:(NSData *)addr inputStream:(NSInputStream *)istr outputStream:(NSOutputStream *)ostr {
+ // if the delegate implements the delegate method, call it
+ if (self.delegate && [self.delegate respondsToSelector:@selector(didAcceptConnectionForServer:inputStream:outputStream:)]) {
+ [self.delegate didAcceptConnectionForServer:self inputStream:istr outputStream:ostr];
+ }
+}
+
+// This function is called by CFSocket when a new connection comes in.
+// We gather some data here, and convert the function call to a method
+// invocation on TCPServer.
+static void TCPServerAcceptCallBack(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *data, void *info) {
+ TCPServer *server = (TCPServer *)info;
+ if (kCFSocketAcceptCallBack == type) {
+ // for an AcceptCallBack, the data parameter is a pointer to a CFSocketNativeHandle
+ CFSocketNativeHandle nativeSocketHandle = *(CFSocketNativeHandle *)data;
+ uint8_t name[SOCK_MAXADDRLEN];
+ socklen_t namelen = sizeof(name);
+ NSData *peer = nil;
+ if (0 == getpeername(nativeSocketHandle, (struct sockaddr *)name, &namelen)) {
+ peer = [NSData dataWithBytes:name length:namelen];
+ }
+ CFReadStreamRef readStream = NULL;
+ CFWriteStreamRef writeStream = NULL;
+ CFStreamCreatePairWithSocket(kCFAllocatorDefault, nativeSocketHandle, &readStream, &writeStream);
+ if (readStream && writeStream) {
+ CFReadStreamSetProperty(readStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
+ CFWriteStreamSetProperty(writeStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
+ [server handleNewConnectionFromAddress:peer inputStream:(NSInputStream *)readStream outputStream:(NSOutputStream *)writeStream];
+ } else {
+ // on any failure, need to destroy the CFSocketNativeHandle
+ // since we are not going to use it any more
+ close(nativeSocketHandle);
+ }
+ if (readStream) CFRelease(readStream);
+ if (writeStream) CFRelease(writeStream);
+ }
+}
+
+- (BOOL)start:(NSError **)error {
+ CFSocketContext socketCtxt = {0, self, NULL, NULL, NULL};
+ _ipv4socket = CFSocketCreate(kCFAllocatorDefault, PF_INET, SOCK_STREAM, IPPROTO_TCP, kCFSocketAcceptCallBack, (CFSocketCallBack)&TCPServerAcceptCallBack, &socketCtxt);
+
+ if (NULL == _ipv4socket) {
+ if (error) *error = [[NSError alloc] initWithDomain:TCPServerErrorDomain code:kTCPServerNoSocketsAvailable userInfo:nil];
+ if (_ipv4socket) CFRelease(_ipv4socket);
+ _ipv4socket = NULL;
+ return NO;
+ }
+
+
+ int yes = 1;
+ setsockopt(CFSocketGetNative(_ipv4socket), SOL_SOCKET, SO_REUSEADDR, (void *)&yes, sizeof(yes));
+
+ // set up the IPv4 endpoint; use port 0, so the kernel will choose an arbitrary port for us, which will be advertised using Bonjour
+ struct sockaddr_in addr4;
+ memset(&addr4, 0, sizeof(addr4));
+ addr4.sin_len = sizeof(addr4);
+ addr4.sin_family = AF_INET;
+ addr4.sin_port = htons(9418);
+ addr4.sin_addr.s_addr = htonl(INADDR_ANY);
+ NSData *address4 = [NSData dataWithBytes:&addr4 length:sizeof(addr4)];
+
+ if (kCFSocketSuccess != CFSocketSetAddress(_ipv4socket, (CFDataRef)address4)) {
+ if (error) *error = [[NSError alloc] initWithDomain:TCPServerErrorDomain code:kTCPServerCouldNotBindToIPv4Address userInfo:nil];
+ if (_ipv4socket) CFRelease(_ipv4socket);
+ _ipv4socket = NULL;
+ return NO;
+ }
+
+ // now that the binding was successful, we get the port number
+ // -- we will need it for the NSNetService
+ NSData *addr = [(NSData *)CFSocketCopyAddress(_ipv4socket) autorelease];
+ memcpy(&addr4, [addr bytes], [addr length]);
+ self.port = ntohs(addr4.sin_port);
+ NSLog(@"created server: %d", self.port);
+
+ // set up the run loop sources for the sockets
+ CFRunLoopRef cfrl = CFRunLoopGetCurrent();
+ CFRunLoopSourceRef source4 = CFSocketCreateRunLoopSource(kCFAllocatorDefault, _ipv4socket, 0);
+ CFRunLoopAddSource(cfrl, source4, kCFRunLoopCommonModes);
+ CFRelease(source4);
+
+ return YES;
+}
+
+- (BOOL)stop {
+ [self disableBonjour];
+
+ if (_ipv4socket) {
+ CFSocketInvalidate(_ipv4socket);
+ CFRelease(_ipv4socket);
+ _ipv4socket = NULL;
+ }
+
+ return YES;
+}
+
+- (BOOL) enableBonjourWithDomain:(NSString*)domain applicationProtocol:(NSString*)protocol name:(NSString*)name
+{
+ if(![domain length])
+ domain = @""; //Will use default Bonjour registration doamins, typically just ".local"
+ if(![name length])
+ name = @""; //Will use default Bonjour name, e.g. the name assigned to the device in iTunes
+
+ if(!protocol || ![protocol length] || _ipv4socket == NULL)
+ return NO;
+
+ NSLog(@"on domain: %@", domain);
+
+ self.netService = [[NSNetService alloc] initWithDomain:domain type:protocol name:name port:self.port];
+ if(self.netService == nil)
+ return NO;
+
+ [self.netService scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
+ [self.netService publish];
+ [self.netService setDelegate:self];
+
+ return YES;
+}
+
+/*
+ Bonjour will not allow conflicting service instance names (in the same domain), and may have automatically renamed
+ the service if there was a conflict. We pass the name back to the delegate so that the name can be displayed to
+ the user.
+ See http://developer.apple.com/networking/bonjour/faq.html for more information.
+ */
+
+- (void)netServiceDidPublish:(NSNetService *)sender
+{
+ if (self.delegate && [self.delegate respondsToSelector:@selector(serverDidEnableBonjour:withName:)])
+ [self.delegate serverDidEnableBonjour:self withName:sender.name];
+}
+
+- (void)netService:(NSNetService *)sender didNotPublish:(NSDictionary *)errorDict
+{
+ [super netServiceDidPublish:sender];
+ if(self.delegate && [self.delegate respondsToSelector:@selector(server:didNotEnableBonjour:)])
+ [self.delegate server:self didNotEnableBonjour:errorDict];
+}
+
+- (void) disableBonjour
+{
+ if(self.netService) {
+ [self.netService stop];
+ [self.netService removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
+ self.netService = nil;
+ }
+}
+
+- (NSString*) description
+{
+ return [NSString stringWithFormat:@"<%@ = 0x%08X | p %d | ns %@>", [self class], (long)self, self.port, self.netService];
+}
+
++ (NSString*) bonjourTypeFromIdentifier:(NSString*)identifier {
+ if (![identifier length])
+ return nil;
+
+ return [NSString stringWithFormat:@"_%@._tcp.", identifier];
+}
+
+@end
27 Picker.h
@@ -0,0 +1,27 @@
+/*
+
+File: Picker.h
+Abstract:
+ A view that displays both the currently advertised game name and a list of
+other games
+ available on the local network (discovered & displayed by
+BrowserViewController).
+
+*/
+
+#import <UIKit/UIKit.h>
+#import "BrowserViewController.h"
+
+@interface Picker : UIView {
+
+@private
+ UILabel* _gameNameLabel;
+ BrowserViewController* _bvc;
+}
+
+@property (nonatomic, assign) id<BrowserViewControllerDelegate> delegate;
+@property (nonatomic, copy) NSString* gameName;
+
+- (id)initWithFrame:(CGRect)frame type:(NSString *)type;
+
+@end
117 Picker.m
@@ -0,0 +1,117 @@
+/*
+
+*/
+
+#import "Picker.h"
+
+#define kOffset 5.0
+
+@interface Picker ()
+@property (nonatomic, retain, readwrite) BrowserViewController* bvc;
+@property (nonatomic, retain, readwrite) UILabel* gameNameLabel;
+@end
+
+@implementation Picker
+
+@synthesize bvc = _bvc;
+@synthesize gameNameLabel = _gameNameLabel;
+
+- (id)initWithFrame:(CGRect)frame type:(NSString*)type {
+ if ((self = [super initWithFrame:frame])) {
+ self.bvc = [[BrowserViewController alloc] initWithTitle:nil showDisclosureIndicators:NO showCancelButton:NO];
+ [self.bvc searchForServicesOfType:type inDomain:@"local"];
+
+ self.opaque = YES;
+ self.backgroundColor = [UIColor blackColor];
+
+ UIImageView* img = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"bg.png"]];
+ [self addSubview:img];
+ [img release];
+
+ CGFloat runningY = kOffset;
+ CGFloat width = self.bounds.size.width - 2 * kOffset;
+
+ UILabel* label = [[UILabel alloc] initWithFrame:CGRectZero];
+ [label setTextAlignment:UITextAlignmentCenter];
+ [label setFont:[UIFont boldSystemFontOfSize:15.0]];
+ [label setTextColor:[UIColor whiteColor]];
+ [label setShadowColor:[UIColor colorWithWhite:0.0 alpha:0.75]];
+ [label setShadowOffset:CGSizeMake(1,1)];
+ [label setBackgroundColor:[UIColor clearColor]];
+ label.text = @"Git Server At";
+ label.numberOfLines = 1;
+ [label sizeToFit];
+ label.frame = CGRectMake(kOffset, runningY, width, label.frame.size.height);
+ [self addSubview:label];
+
+ runningY += label.bounds.size.height;
+ [label release];
+
+ self.gameNameLabel = [[UILabel alloc] initWithFrame:CGRectZero];
+ [self.gameNameLabel setTextAlignment:UITextAlignmentCenter];
+ [self.gameNameLabel setFont:[UIFont boldSystemFontOfSize:24.0]];
+ [self.gameNameLabel setLineBreakMode:UILineBreakModeTailTruncation];
+ [self.gameNameLabel setTextColor:[UIColor whiteColor]];
+ [self.gameNameLabel setShadowColor:[UIColor colorWithWhite:0.0 alpha:0.75]];
+ [self.gameNameLabel setShadowOffset:CGSizeMake(1,1)];
+ [self.gameNameLabel setBackgroundColor:[UIColor clearColor]];
+ [self.gameNameLabel setText:@"Default Name"];
+ [self.gameNameLabel sizeToFit];
+ [self.gameNameLabel setFrame:CGRectMake(kOffset, runningY, width, self.gameNameLabel.frame.size.height)];
+ [self.gameNameLabel setText:@""];
+ [self addSubview:self.gameNameLabel];
+
+ runningY += self.gameNameLabel.bounds.size.height + kOffset * 2;
+
+ label = [[UILabel alloc] initWithFrame:CGRectZero];
+ [label setTextAlignment:UITextAlignmentCenter];
+ [label setFont:[UIFont boldSystemFontOfSize:15.0]];
+ [label setTextColor:[UIColor whiteColor]];
+ [label setShadowColor:[UIColor colorWithWhite:0.0 alpha:0.75]];
+ [label setShadowOffset:CGSizeMake(1,1)];
+ [label setBackgroundColor:[UIColor clearColor]];
+ label.text = @"git clone";
+ label.numberOfLines = 1;
+ [label sizeToFit];
+ label.frame = CGRectMake(kOffset, runningY, width, label.frame.size.height);
+ [self addSubview:label];
+
+ runningY += label.bounds.size.height + 2;
+
+ [self.bvc.view setFrame:CGRectMake(0, runningY, self.bounds.size.width, self.bounds.size.height - runningY)];
+ [self addSubview:self.bvc.view];
+
+ }
+
+ return self;
+}
+
+
+- (void)dealloc {
+ // Cleanup any running resolve and free memory
+ [self.bvc release];
+ [self.gameNameLabel release];
+
+ [super dealloc];
+}
+
+
+- (id<BrowserViewControllerDelegate>)delegate {
+ return self.bvc.delegate;
+}
+
+
+- (void)setDelegate:(id<BrowserViewControllerDelegate>)delegate {
+ [self.bvc setDelegate:delegate];
+}
+
+- (NSString *)gameName {
+ return self.gameNameLabel.text;
+}
+
+- (void)setGameName:(NSString *)string {
+ [self.gameNameLabel setText:string];
+ [self.bvc setOwnName:string];
+}
+
+@end
51 Prefix.pch
@@ -0,0 +1,51 @@
+/*
+
+File: Prefix.pch
+Abstract: This file is included for support purposes and isn't necessary for
+understanding this sample.
+
+Version: 1.0
+
+Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc.
+("Apple") in consideration of your agreement to the following terms, and your
+use, installation, modification or redistribution of this Apple software
+constitutes acceptance of these terms. If you do not agree with these terms,
+please do not use, install, modify or redistribute this Apple software.
+
+In consideration of your agreement to abide by the following terms, and subject
+to these terms, Apple grants you a personal, non-exclusive license, under
+Apple's copyrights in this original Apple software (the "Apple Software"), to
+use, reproduce, modify and redistribute the Apple Software, with or without
+modifications, in source and/or binary forms; provided that if you redistribute
+the Apple Software in its entirety and without modifications, you must retain
+this notice and the following text and disclaimers in all such redistributions
+of the Apple Software.
+Neither the name, trademarks, service marks or logos of Apple Inc. may be used
+to endorse or promote products derived from the Apple Software without specific
+prior written permission from Apple. Except as expressly stated in this notice,
+no other rights or licenses, express or implied, are granted by Apple herein,
+including but not limited to any patent rights that may be infringed by your
+derivative works or by other works in which the Apple Software may be
+incorporated.
+
+The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR
+DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF
+CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Copyright (C) 2008 Apple Inc. All Rights Reserved.
+
+*/
+
+#ifdef __OBJC__
+ #import <UIKit/UIKit.h>
+#endif
72 ReadMe.txt
@@ -0,0 +1,72 @@
+
+WiTap
+
+================================================================================
+DESCRIPTION:
+
+The WiTap sample application demonstrates how to achieve network communication between applications. Using Bonjour, the application both advertises itself on the local network and displays a list of other instances of this application on the network.
+
+Simply build the sample using Xcode and run it in the simulator or on the device. Wait for another player to connect or select a game to connect to. Once connected, tap one or more colored pads on a device to see them highlighted simultaneously on the remote device.
+
+===========================================================================
+BUILD REQUIREMENTS:
+
+Mac OS X 10.5.3, Xcode 3.1, iPhone OS 2.0
+
+===========================================================================
+RUNTIME REQUIREMENTS:
+
+Mac OS X 10.5.3, iPhone OS 2.0
+
+===========================================================================
+PACKAGING LIST:
+
+AppController.h
+AppController.m
+UIApplication's delegate class, the central controller of the application.
+
+TapView.h
+TapView.m
+UIView subclass that can highlight itself when locally or remotely tapped.
+
+Picker.h
+Picker.m
+A view that displays both the currently advertised game name and a list of other games
+available on the local network (discovered & displayed by BrowserViewController).
+
+Networking/TCPServer.h
+Networking/TCPServer.m
+A TCP server that listens on an arbitrary port.
+
+Networking/BrowserViewController.h
+Networking/BrowserViewController.m
+View controller for the service instance list.
+This object manages a NSNetServiceBrowser configured to look for Bonjour services.
+It has an array of NSNetService objects that are displayed in a table view.
+When the service browser reports that it has discovered a service, the corresponding NSNetService is added to the array.
+When a service goes away, the corresponding NSNetService is removed from the array.
+Selecting an item in the table view asynchronously resolves the corresponding net service.
+When that resolution completes, the delegate is called with the corresponding net service.
+
+main.m
+The main file for the WiTap application.
+
+===========================================================================
+CHANGES FROM PREVIOUS VERSIONS:
+
+Version 1.5
+- Updated for and tested with iPhone OS 2.0. First public release.
+
+Version 1.4
+- Updated for Beta 7.
+- Code clean up.
+- Improved Bonjour support.
+
+Version 1.3
+- Updated for Beta 4.
+- Added code signing.
+
+Version 1.2
+- Added icon.
+
+Copyright ©2008 Apple Inc. All rights reserved.
60 TapView.h
@@ -0,0 +1,60 @@
+/*
+
+File: TapView.h
+Abstract: UIView subclass that can highlight itself when locally or remotely
+tapped.
+
+Version: 1.5
+
+Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc.
+("Apple") in consideration of your agreement to the following terms, and your
+use, installation, modification or redistribution of this Apple software
+constitutes acceptance of these terms. If you do not agree with these terms,
+please do not use, install, modify or redistribute this Apple software.
+
+In consideration of your agreement to abide by the following terms, and subject
+to these terms, Apple grants you a personal, non-exclusive license, under
+Apple's copyrights in this original Apple software (the "Apple Software"), to
+use, reproduce, modify and redistribute the Apple Software, with or without
+modifications, in source and/or binary forms; provided that if you redistribute
+the Apple Software in its entirety and without modifications, you must retain
+this notice and the following text and disclaimers in all such redistributions
+of the Apple Software.
+Neither the name, trademarks, service marks or logos of Apple Inc. may be used
+to endorse or promote products derived from the Apple Software without specific
+prior written permission from Apple. Except as expressly stated in this notice,
+no other rights or licenses, express or implied, are granted by Apple herein,
+including but not limited to any patent rights that may be infringed by your
+derivative works or by other works in which the Apple Software may be
+incorporated.
+
+The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR
+DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF
+CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Copyright (C) 2008 Apple Inc. All Rights Reserved.
+
+*/
+
+#import <UIKit/UIKit.h>
+
+//CLASS INTERFACES:
+
+@interface TapView : UIView
+{
+ BOOL localTouch;
+ BOOL remoteTouch;
+}
+- (void) touchDown:(BOOL)remote;
+- (void) touchUp:(BOOL)remote;
+@end
77 TapView.m
@@ -0,0 +1,77 @@
+/*
+
+File: TapView.m
+Abstract: UIView subclass that can highlight itself when locally or remotely
+tapped.
+
+Version: 1.5
+
+Copyright (C) 2008 Apple Inc. All Rights Reserved.
+
+*/
+
+#import "AppController.h"
+
+//CONSTANTS:
+
+#define kActivationInset 10
+
+//CLASS IMPLEMENTATIONS:
+
+@implementation TapView
+
+- (void) touchDown:(BOOL)remote
+{
+ //Set "tap down" visual state if necessary
+ if(!localTouch && !remoteTouch)
+ self.frame=CGRectInset(self.frame, kActivationInset, kActivationInset);
+
+ if (remote)
+ remoteTouch = YES;
+ else
+ localTouch = YES;
+}
+
+- (void) touchUp:(BOOL)remote
+{
+ BOOL wasDown = localTouch || remoteTouch;
+
+ if (remote)
+ remoteTouch = NO;
+ else
+ localTouch = NO;
+
+ BOOL isDown = localTouch || remoteTouch;
+
+ //Run "tap up" visual animation if necessary
+ if(wasDown != isDown) {
+ [UIView beginAnimations:nil context:NULL];
+ [UIView setAnimationDuration:0.1];
+ self.frame = CGRectInset(self.frame, -kActivationInset, -kActivationInset);
+ [UIView commitAnimations];
+ }
+}
+
+- (void) localTouchUp
+{
+ [self touchUp:NO];
+ [(AppController*)[[UIApplication sharedApplication] delegate] deactivateView:self];
+}
+
+- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
+{
+ [self touchDown:NO];
+ [(AppController*)[[UIApplication sharedApplication] delegate] activateView:self];
+}
+
+- (void) touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
+{
+ [self localTouchUp];
+}
+
+- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
+{
+ [self localTouchUp];
+}
+
+@end
BIN  bg.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 build/Debug-iphonesimulator/WiTap.app.dSYM/Contents/Info.plist
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//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>CFBundleIdentifier</key>
+ <string>com.apple.xcode.dsym.com.yourcompany.WiTap</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>dSYM</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.5</string>
+ <key>dSYM_UUID</key>
+ <dict>
+ <key>i386</key>
+ <string>82286A46-E67F-7671-D111-B2854B7C8BE9</string>
+ </dict>
+ </dict>
+</plist>
BIN  build/Debug-iphonesimulator/WiTap.app.dSYM/Contents/Resources/DWARF/WiTap
Binary file not shown
BIN  build/Debug-iphonesimulator/WiTap.app/Default.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 build/Debug-iphonesimulator/WiTap.app/Info.plist
@@ -0,0 +1,28 @@
+<?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>WiTap</string>
+ <key>CFBundleExecutable</key>
+ <string>WiTap</string>
+ <key>CFBundleIconFile</key>
+ <string>icon.png</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.yourcompany.WiTap</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleVersion</key>
+ <string>1.5</string>
+ <key>DTPlatformName</key>
+ <string>iphonesimulator</string>
+ <key>DTSDKName</key>
+ <string>iphonesimulator2.0</string>
+ <key>UIRequiresPersistentWiFi</key>
+ <true/>
+</dict>
+</plist>
1  build/Debug-iphonesimulator/WiTap.app/PkgInfo
@@ -0,0 +1 @@
+APPL????
BIN  build/Debug-iphonesimulator/WiTap.app/WiTap
Binary file not shown
BIN  build/Debug-iphonesimulator/WiTap.app/bg.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  build/Debug-iphonesimulator/WiTap.app/icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 build/Debug-iphonesimulator/iGitHub.app.dSYM/Contents/Info.plist
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//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>CFBundleIdentifier</key>
+ <string>com.apple.xcode.dsym.com.yourcompany.iGitHub</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>dSYM</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>dSYM_UUID</key>
+ <dict>
+ <key>i386</key>
+ <string>CA15F2E9-073A-BBC6-FAA6-A17450680194</string>
+ </dict>
+ </dict>
+</plist>
BIN  build/Debug-iphonesimulator/iGitHub.app.dSYM/Contents/Resources/DWARF/iGitHub
Binary file not shown
BIN  build/Debug-iphonesimulator/iGitHub.app/Default.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 build/Debug-iphonesimulator/iGitHub.app/Info.plist
@@ -0,0 +1,28 @@
+<?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>iGitHub</string>
+ <key>CFBundleExecutable</key>
+ <string>iGitHub</string>
+ <key>CFBundleIconFile</key>
+ <string>icon.png</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.yourcompany.iGitHub</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>DTPlatformName</key>
+ <string>iphonesimulator</string>
+ <key>DTSDKName</key>
+ <string>iphonesimulator2.0</string>
+ <key>UIRequiresPersistentWiFi</key>
+ <true/>
+</dict>
+</plist>
1  build/Debug-iphonesimulator/iGitHub.app/PkgInfo
@@ -0,0 +1 @@
+APPL????
BIN  build/Debug-iphonesimulator/iGitHub.app/bg.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  build/Debug-iphonesimulator/iGitHub.app/iGitHub
Binary file not shown
BIN  build/Debug-iphonesimulator/iGitHub.app/icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  build/WiTap.build/Debug-iphonesimulator/WiTap.build/Objects-normal/i386/AppController.o
Binary file not shown
BIN  build/WiTap.build/Debug-iphonesimulator/WiTap.build/Objects-normal/i386/BrowserViewController.o
Binary file not shown
BIN  build/WiTap.build/Debug-iphonesimulator/WiTap.build/Objects-normal/i386/Picker.o
Binary file not shown
BIN  build/WiTap.build/Debug-iphonesimulator/WiTap.build/Objects-normal/i386/TCPServer.o
Binary file not shown
BIN  build/WiTap.build/Debug-iphonesimulator/WiTap.build/Objects-normal/i386/TapView.o
Binary file not shown
6 build/WiTap.build/Debug-iphonesimulator/WiTap.build/Objects-normal/i386/WiTap.LinkFileList
@@ -0,0 +1,6 @@
+/Users/schacon/Downloads/WiTap/build/WiTap.build/Debug-iphonesimulator/WiTap.build/Objects-normal/i386/main.o
+/Users/schacon/Downloads/WiTap/build/WiTap.build/Debug-iphonesimulator/WiTap.build/Objects-normal/i386/AppController.o
+/Users/schacon/Downloads/WiTap/build/WiTap.build/Debug-iphonesimulator/WiTap.build/Objects-normal/i386/TCPServer.o
+/Users/schacon/Downloads/WiTap/build/WiTap.build/Debug-iphonesimulator/WiTap.build/Objects-normal/i386/TapView.o
+/Users/schacon/Downloads/WiTap/build/WiTap.build/Debug-iphonesimulator/WiTap.build/Objects-normal/i386/BrowserViewController.o
+/Users/schacon/Downloads/WiTap/build/WiTap.build/Debug-iphonesimulator/WiTap.build/Objects-normal/i386/Picker.o
BIN  build/WiTap.build/Debug-iphonesimulator/WiTap.build/Objects-normal/i386/main.o
Binary file not shown
BIN  build/WiTap.build/Debug-iphonesimulator/WiTap.build/WiTap-all-target-headers.hmap
Binary file not shown
BIN  build/WiTap.build/Debug-iphonesimulator/WiTap.build/WiTap-generated-files.hmap
Binary file not shown
BIN  build/WiTap.build/Debug-iphonesimulator/WiTap.build/WiTap-own-target-headers.hmap
Binary file not shown
BIN  build/WiTap.build/Debug-iphonesimulator/WiTap.build/WiTap-project-headers.hmap
Binary file not shown
BIN  build/WiTap.build/Debug-iphonesimulator/WiTap.build/WiTap.hmap
Binary file not shown
BIN  build/WiTap.build/WiTap.pbxindex/categories.pbxbtree
Binary file not shown
BIN  build/WiTap.build/WiTap.pbxindex/cdecls.pbxbtree
Binary file not shown
BIN  build/WiTap.build/WiTap.pbxindex/decls.pbxbtree
Binary file not shown
BIN  build/WiTap.build/WiTap.pbxindex/files.pbxbtree
Binary file not shown
BIN  build/WiTap.build/WiTap.pbxindex/imports.pbxbtree
Binary file not shown
BIN  build/WiTap.build/WiTap.pbxindex/pbxindex.header
Binary file not shown
BIN  build/WiTap.build/WiTap.pbxindex/protocols.pbxbtree
Binary file not shown
BIN  build/WiTap.build/WiTap.pbxindex/refs.pbxbtree
Binary file not shown
BIN  build/WiTap.build/WiTap.pbxindex/strings.pbxstrings/control
Binary file not shown
BIN  build/WiTap.build/WiTap.pbxindex/strings.pbxstrings/strings
Binary file not shown
BIN  build/WiTap.build/WiTap.pbxindex/subclasses.pbxbtree
Binary file not shown
BIN  build/WiTap.build/WiTap.pbxindex/symbols0.pbxsymbols
Binary file not shown
BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/Objects-normal/i386/AppController.o
Binary file not shown
BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/Objects-normal/i386/BrowserViewController.o
Binary file not shown
BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/Objects-normal/i386/Picker.o
Binary file not shown
BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/Objects-normal/i386/TCPServer.o
Binary file not shown
BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/Objects-normal/i386/TapView.o
Binary file not shown
6 build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/Objects-normal/i386/WiTap.LinkFileList
@@ -0,0 +1,6 @@
+/Users/schacon/projects/iGitHub/build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/Objects-normal/i386/main.o
+/Users/schacon/projects/iGitHub/build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/Objects-normal/i386/AppController.o
+/Users/schacon/projects/iGitHub/build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/Objects-normal/i386/TCPServer.o
+/Users/schacon/projects/iGitHub/build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/Objects-normal/i386/TapView.o
+/Users/schacon/projects/iGitHub/build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/Objects-normal/i386/BrowserViewController.o
+/Users/schacon/projects/iGitHub/build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/Objects-normal/i386/Picker.o
6 build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/Objects-normal/i386/iGitHub.LinkFileList
@@ -0,0 +1,6 @@
+/Users/schacon/projects/iGitHub/build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/Objects-normal/i386/main.o
+/Users/schacon/projects/iGitHub/build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/Objects-normal/i386/AppController.o
+/Users/schacon/projects/iGitHub/build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/Objects-normal/i386/TCPServer.o
+/Users/schacon/projects/iGitHub/build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/Objects-normal/i386/TapView.o
+/Users/schacon/projects/iGitHub/build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/Objects-normal/i386/BrowserViewController.o
+/Users/schacon/projects/iGitHub/build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/Objects-normal/i386/Picker.o
BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/Objects-normal/i386/main.o
Binary file not shown
BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/WiTap-all-target-headers.hmap
Binary file not shown
BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/WiTap-generated-files.hmap
Binary file not shown
BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/WiTap-own-target-headers.hmap
Binary file not shown
BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/WiTap-project-headers.hmap
Binary file not shown
BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/WiTap.hmap
Binary file not shown
BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/iGitHub-all-target-headers.hmap
Binary file not shown
BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/iGitHub-generated-files.hmap
Binary file not shown
BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/iGitHub-own-target-headers.hmap
Binary file not shown
BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/iGitHub-project-headers.hmap
Binary file not shown
BIN  build/iGitHub.build/Debug-iphonesimulator/iGitHub.build/iGitHub.hmap
Binary file not shown
BIN  build/iGitHub.build/iGitHub.pbxindex/categories.pbxbtree
Binary file not shown
BIN  build/iGitHub.build/iGitHub.pbxindex/cdecls.pbxbtree
Binary file not shown
BIN  build/iGitHub.build/iGitHub.pbxindex/decls.pbxbtree
Binary file not shown
BIN  build/iGitHub.build/iGitHub.pbxindex/files.pbxbtree
Binary file not shown
BIN  build/iGitHub.build/iGitHub.pbxindex/imports.pbxbtree
Binary file not shown
BIN  build/iGitHub.build/iGitHub.pbxindex/pbxindex.header
Binary file not shown
BIN  build/iGitHub.build/iGitHub.pbxindex/protocols.pbxbtree
Binary file not shown
BIN  build/iGitHub.build/iGitHub.pbxindex/refs.pbxbtree
Binary file not shown
BIN  build/iGitHub.build/iGitHub.pbxindex/strings.pbxstrings/control
Binary file not shown
BIN  build/iGitHub.build/iGitHub.pbxindex/strings.pbxstrings/strings
Binary file not shown
BIN  build/iGitHub.build/iGitHub.pbxindex/subclasses.pbxbtree
Binary file not shown
BIN  build/iGitHub.build/iGitHub.pbxindex/symbols0.pbxsymbols
Binary file not shown
302 iGitHub.xcodeproj/project.pbxproj
@@ -0,0 +1,302 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 45;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 188D407F0D6D2F160076AE1E /* TapView.m in Sources */ = {isa = PBXBuildFile; fileRef = 188D407D0D6D2F160076AE1E /* TapView.m */; };
+ 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; };
+ 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 */; };
+ 2D500B1C0D5A766900DBA0E3 /* AppController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D500B1B0D5A766900DBA0E3 /* AppController.m */; };
+ 2D500FA20D5A86A600DBA0E3 /* TCPServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D500F920D5A86A600DBA0E3 /* TCPServer.m */; };
+ 2D500FB40D5A86C000DBA0E3 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2D500FB20D5A86C000DBA0E3 /* SystemConfiguration.framework */; };
+ 4A50295F0DF7068E00D72A3B /* BrowserViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4A50295E0DF7068E00D72A3B /* BrowserViewController.m */; };
+ 4A6968FE0E1AD83800DCB40C /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 4A6968FD0E1AD83800DCB40C /* Default.png */; };
+ 4ACBF2160E1AC84C002CC43E /* bg.png in Resources */ = {isa = PBXBuildFile; fileRef = 4ACBF2150E1AC84C002CC43E /* bg.png */; };
+ 4AFB75470DF7691E00DCF235 /* Picker.m in Sources */ = {isa = PBXBuildFile; fileRef = 4AFB75460DF7691E00DCF235 /* Picker.m */; };
+ 8406D2F00DF4B487005DDED6 /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 8406D2EF0DF4B487005DDED6 /* icon.png */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 188D407D0D6D2F160076AE1E /* TapView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TapView.m; sourceTree = "<group>"; };
+ 188D407E0D6D2F160076AE1E /* TapView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TapView.h; sourceTree = "<group>"; };
+ 1BFA8F9A0DA6BA0400E6B5C8 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.txt; sourceTree = "<group>"; };
+ 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+ 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
+ 1D6058910D05DD3D006BFB54 /* iGitHub.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iGitHub.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
+ 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+ 2D500B1A0D5A766900DBA0E3 /* AppController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppController.h; sourceTree = "<group>"; };
+ 2D500B1B0D5A766900DBA0E3 /* AppController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppController.m; sourceTree = "<group>"; };
+ 2D500F910D5A86A600DBA0E3 /* TCPServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TCPServer.h; path = Networking/TCPServer.h; sourceTree = "<group>"; };
+ 2D500F920D5A86A600DBA0E3 /* TCPServer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TCPServer.m; path = Networking/TCPServer.m; sourceTree = "<group>"; };
+ 2D500FB20D5A86C000DBA0E3 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
+ 32CA4F630368D1EE00C91783 /* Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Prefix.pch; sourceTree = "<group>"; };
+ 4A50295D0DF7068E00D72A3B /* BrowserViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BrowserViewController.h; path = Networking/BrowserViewController.h; sourceTree = "<group>"; };
+ 4A50295E0DF7068E00D72A3B /* BrowserViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BrowserViewController.m; path = Networking/BrowserViewController.m; sourceTree = "<group>"; };
+ 4A6968FD0E1AD83800DCB40C /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = "<group>"; };
+ 4ACBF2150E1AC84C002CC43E /* bg.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = bg.png; sourceTree = "<group>"; };
+ 4AFB75450DF7691E00DCF235 /* Picker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Picker.h; sourceTree = "<group>"; };
+ 4AFB75460DF7691E00DCF235 /* Picker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Picker.m; sourceTree = "<group>"; };
+ 8406D2EF0DF4B487005DDED6 /* icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon.png; sourceTree = "<group>"; };
+ 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = 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 */,
+ 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */,
+ 2D500FB40D5A86C000DBA0E3 /* SystemConfiguration.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 19C28FACFE9D520D11CA2CBB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 1D6058910D05DD3D006BFB54 /* iGitHub.app */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = {
+ isa = PBXGroup;
+ children = (
+ 1BFA8F9A0DA6BA0400E6B5C8 /* ReadMe.txt */,
+ 2D500B1D0D5A766B00DBA0E3 /* Classes */,
+ 2D500B6F0D5A793600DBA0E3 /* Support */,
+ 29B97315FDCFA39411CA2CEA /* Other Sources */,
+ 29B97317FDCFA39411CA2CEA /* Resources */,
+ 29B97323FDCFA39411CA2CEA /* Frameworks */,
+ 19C28FACFE9D520D11CA2CBB /* Products */,
+ );
+ name = CustomTemplate;
+ sourceTree = "<group>";
+ };
+ 29B97315FDCFA39411CA2CEA /* Other Sources */ = {
+ isa = PBXGroup;
+ children = (
+ 32CA4F630368D1EE00C91783 /* Prefix.pch */,
+ 29B97316FDCFA39411CA2CEA /* main.m */,
+ );
+ name = "Other Sources";
+ sourceTree = "<group>";
+ };
+ 29B97317FDCFA39411CA2CEA /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 4ACBF2150E1AC84C002CC43E /* bg.png */,
+ 8406D2EF0DF4B487005DDED6 /* icon.png */,
+ 8D1107310486CEB800E47090 /* Info.plist */,
+ 4A6968FD0E1AD83800DCB40C /* Default.png */,
+ );
+ name = Resources;
+ sourceTree = "<group>";
+ };
+ 29B97323FDCFA39411CA2CEA /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 2D500FB20D5A86C000DBA0E3 /* SystemConfiguration.framework */,
+ 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */,
+ 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */,
+ 1D30AB110D05D00D00671497 /* Foundation.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+ 2D500B1D0D5A766B00DBA0E3 /* Classes */ = {
+ isa = PBXGroup;
+ children = (
+ 2D500B1A0D5A766900DBA0E3 /* AppController.h */,
+ 2D500B1B0D5A766900DBA0E3 /* AppController.m */,
+ 188D407E0D6D2F160076AE1E /* TapView.h */,
+ 188D407D0D6D2F160076AE1E /* TapView.m */,
+ 4AFB75450DF7691E00DCF235 /* Picker.h */,
+ 4AFB75460DF7691E00DCF235 /* Picker.m */,
+ );
+ name = Classes;
+ sourceTree = "<group>";
+ };
+ 2D500B6F0D5A793600DBA0E3 /* Support */ = {
+ isa = PBXGroup;
+ children = (
+ 4A50295D0DF7068E00D72A3B /* BrowserViewController.h */,
+ 4A50295E0DF7068E00D72A3B /* BrowserViewController.m */,
+ 2D500F910D5A86A600DBA0E3 /* TCPServer.h */,
+ 2D500F920D5A86A600DBA0E3 /* TCPServer.m */,
+ );
+ name = Support;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 1D6058900D05DD3D006BFB54 /* iGitHub */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "iGitHub" */;
+ buildPhases = (
+ 1D60588D0D05DD3D006BFB54 /* Resources */,
+ 1D60588E0D05DD3D006BFB54 /* Sources */,
+ 1D60588F0D05DD3D006BFB54 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = iGitHub;
+ productName = foo;
+ productReference = 1D6058910D05DD3D006BFB54 /* iGitHub.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 "iGitHub" */;
+ compatibilityVersion = "Xcode 3.1";
+ hasScannedForEncodings = 1;
+ mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 1D6058900D05DD3D006BFB54 /* iGitHub */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 1D60588D0D05DD3D006BFB54 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8406D2F00DF4B487005DDED6 /* icon.png in Resources */,
+ 4ACBF2160E1AC84C002CC43E /* bg.png in Resources */,
+ 4A6968FE0E1AD83800DCB40C /* Default.png in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 1D60588E0D05DD3D006BFB54 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 1D60589B0D05DD56006BFB54 /* main.m in Sources */,
+ 2D500B1C0D5A766900DBA0E3 /* AppController.m in Sources */,
+ 2D500FA20D5A86A600DBA0E3 /* TCPServer.m in Sources */,
+ 188D407F0D6D2F160076AE1E /* TapView.m in Sources */,
+ 4A50295F0DF7068E00D72A3B /* BrowserViewController.m in Sources */,
+ 4AFB75470DF7691E00DCF235 /* Picker.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;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = Prefix.pch;
+ INFOPLIST_FILE = Info.plist;
+ "OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
+ "-framework",
+ CFNetwork,
+ );
+ "OTHER_LDFLAGS[sdk=iphonesimulator2.0][arch=*]" = (
+ "-framework",
+ CoreServices,
+ );
+ PREBINDING = NO;
+ PRODUCT_NAME = iGitHub;
+ WARNING_CFLAGS = "-Wall";
+ };
+ name = Debug;
+ };
+ 1D6058950D05DD3E006BFB54 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = Prefix.pch;
+ INFOPLIST_FILE = Info.plist;
+ "OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
+ "-framework",
+ CFNetwork,
+ );
+ "OTHER_LDFLAGS[sdk=iphonesimulator2.0][arch=*]" = (
+ "-framework",
+ CoreServices,
+ );
+ PREBINDING = NO;
+ PRODUCT_NAME = WiTap;
+ WARNING_CFLAGS = "-Wall";
+ };
+ name = Release;
+ };
+ C01FCF4F08A954540054247B /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos2.0;
+ };
+ name = Debug;
+ };
+ C01FCF5008A954540054247B /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ SDKROOT = iphoneos2.0;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "iGitHub" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1D6058940D05DD3E006BFB54 /* Debug */,
+ 1D6058950D05DD3E006BFB54 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ C01FCF4E08A954540054247B /* Build configuration list for PBXProject "iGitHub" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C01FCF4F08A954540054247B /* Debug */,
+ C01FCF5008A954540054247B /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
+}
1,394 iGitHub.xcodeproj/schacon.mode1v3
@@ -0,0 +1,1394 @@
+<?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>