Permalink
Browse files

Initial commit

  • Loading branch information...
0 parents commit b3f360470b845754c48e19e3b1ecc7040605da37 @thisandagain committed Jun 18, 2012
12 .gitignore
@@ -0,0 +1,12 @@
+.DS_Store
+*.swp
+*~.nib
+
+build/
+
+.xcodeproj/
+!*.xcodeproj/project.pbxproj
+*.mode1v3
+*.mode2v3
+
+xcuserdata
40 DIYConduit.h
@@ -0,0 +1,40 @@
+//
+// DIYConduit.h
+// conduit
+//
+// Created by Andrew Sliwinski on 6/17/12.
+// Copyright (c) 2012 DIY, Co. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+#import "DIYConduitBridge.h"
+
+@class DIYConduit;
+
+//
+
+@protocol DIYConduitDelegate
+- (void)conduit:(DIYConduit *)conduit receivedMessage:(NSString *)message;
+@end
+
+//
+
+@interface DIYConduit : UIView <DIYConduitBridgeDelegate>
+{
+ @private DIYConduitBridge *bridge;
+}
+
+@property (nonatomic, assign) id <DIYConduitDelegate> delegate;
+@property (nonatomic, retain) UIWebView *webView;
+@property (nonatomic, retain) NSMutableDictionary *headers;
+
+- (void)loadRequest:(NSURLRequest *)request;
+- (void)loadHTMLString:(NSString *)html baseURL:(NSURL *)baseURL;
+
+- (void)addHeader:(NSString *)key withValue:(NSString *)value;
+- (void)removeHeader:(NSString *)key;
+
+- (void)sendMessage:(NSString *)message;
+- (void)resetMessageQueue;
+
+@end
207 DIYConduit.m
@@ -0,0 +1,207 @@
+//
+// DIYConduit.m
+// conduit
+//
+// Created by Andrew Sliwinski on 6/17/12.
+// Copyright (c) 2012 DIY, Co. All rights reserved.
+//
+
+#import "DIYConduit.h"
+
+//
+
+@interface DIYConduit ()
+@property (nonatomic, retain) DIYConduitBridge *bridge;
+@end
+
+//
+
+@implementation DIYConduit
+
+@synthesize delegate = _delegate;
+@synthesize webView = _webView;
+@synthesize bridge = _bridge;
+@synthesize headers = _headers;
+
+#pragma mark - Init
+
+- (void)_init
+{
+ // Webview
+ self.webView = [[UIWebView alloc] initWithFrame:self.frame];
+
+ // Bridge
+ self.bridge = [DIYConduitBridge javascriptBridgeWithDelegate:self];
+ self.webView.delegate = self.bridge;
+
+ // Headers
+ self.headers = [[NSMutableDictionary alloc] init];
+
+ // Add to view
+ [self addSubview:self.webView];
+}
+
+- (id)initWithFrame:(CGRect)frame
+{
+ if((self = [super initWithFrame:frame]))
+ {
+ [self _init];
+ }
+ return self;
+}
+
+- (id)initWithCoder:(NSCoder *)aDecoder
+{
+ if((self = [super initWithCoder:aDecoder]))
+ {
+ [self _init];
+ }
+ return self;
+}
+
+#pragma mark - Public methods
+
+/**
+ * Loads a NSURLRequest into the web view with custom headers appended.
+ *
+ * @param {NSURLRequest} Request
+ *
+ * @return {void}
+ */
+- (void)loadRequest:(NSURLRequest *)request
+{
+ [self.webView loadRequest:[self generateMutableRequestWithRequest:request andHeaders:self.headers]];
+}
+
+/**
+ * Loads HTML into the web view from a string.
+ *
+ * @param {NSString} HTML
+ * @param {NSURL} Base URL reference (usually set to "nil")
+ *
+ * @return {void}
+ */
+- (void)loadHTMLString:(NSString *)html baseURL:(NSURL *)baseURL
+{
+ [self.webView loadHTMLString:html baseURL:baseURL];
+}
+
+/**
+ * Adds a custom header to be reflected in every subsequent request.
+ *
+ * @param {NSString} Header key (e.g. @"x-api-key")
+ * @param {NSString} Header value (e.g. @"mykeygoeshere")
+ *
+ * @return {void}
+ */
+- (void)addHeader:(NSString *)key withValue:(NSString *)value
+{
+ [self.headers setValue:value forKey:[key lowercaseString]];
+}
+
+/**
+ * Removes a header.
+ *
+ * @param {NSString} Header key (e.g. @"x-api-key")
+ *
+ * @return {void}
+ */
+- (void)removeHeader:(NSString *)key
+{
+ [self.headers setValue:nil forKey:[key lowercaseString]];
+}
+
+/**
+ * Sends a message to the bridge.
+ *
+ * @param {NSString} Message
+ *
+ * @return {void}
+ */
+- (void)sendMessage:(NSString *)message
+{
+ [self.bridge sendMessage:message toWebView:self.webView];
+}
+
+/**
+ * Resets the bridge message queue.
+ *
+ * @return {void}
+ */
+- (void)resetMessageQueue
+{
+ [self.bridge resetQueue];
+}
+
+#pragma mark - Private methods
+
+- (NSMutableURLRequest *)generateMutableRequestWithRequest:(NSURLRequest *)_request andHeaders:(NSDictionary *)_headers
+{
+ NSMutableURLRequest *mutableRequest = [_request mutableCopy];
+ for (NSString *key in self.headers)
+ {
+ [mutableRequest setValue:[self.headers valueForKey:key] forHTTPHeaderField:key];
+ }
+
+ return mutableRequest;
+}
+
+#pragma mark - UIWebViewDelegate
+
+- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
+{
+ // Check for local request & bypass custom headers logic
+ if ([[[request URL] absoluteString] isEqualToString:@"about:blank"])
+ {
+ return true;
+ }
+
+ // Storage objects
+ BOOL customHeadersExist = true;
+ NSDictionary *existingHeaders = [request allHTTPHeaderFields];
+
+ // Check that custom headers exist
+ for (NSString *key in self.headers)
+ {
+ if ([existingHeaders objectForKey:key] == nil)
+ {
+ customHeadersExist = false;
+ break;
+ }
+ }
+
+ // If not, append them to the request
+ if (!customHeadersExist)
+ {
+ [self loadRequest:request];
+ return false;
+ }
+
+ return true;
+}
+
+#pragma mark - WebViewJavascriptBridge
+
+- (void)javascriptBridge:(DIYConduitBridge *)bridge receivedMessage:(NSString *)message fromWebView:(UIWebView *)webView
+{
+ [self.delegate conduit:self receivedMessage:message];
+}
+
+#pragma mark - Dealloc
+
+- (void)releaseObjects
+{
+ _delegate = nil;
+
+ [_webView release]; _webView = nil;
+ [_bridge release]; _bridge = nil;
+ [_headers release]; _headers = nil;
+}
+
+- (void)dealloc
+{
+ [self releaseObjects];
+ [super dealloc];
+}
+
+@end
21 DIYConduitBridge.h
@@ -0,0 +1,21 @@
+#import <UIKit/UIKit.h>
+
+@class DIYConduitBridge;
+
+//
+
+@protocol DIYConduitBridgeDelegate <UIWebViewDelegate>
+- (void)javascriptBridge:(DIYConduitBridge *)bridge receivedMessage:(NSString *)message fromWebView:(UIWebView *)webView;
+@end
+
+//
+
+@interface DIYConduitBridge : NSObject <UIWebViewDelegate>
+
+@property (nonatomic, assign) IBOutlet id <DIYConduitBridgeDelegate> delegate;
+
++ (id)javascriptBridgeWithDelegate:(id <DIYConduitBridgeDelegate>)delegate;
+- (void)sendMessage:(NSString *)message toWebView:(UIWebView *)webView;
+- (void)resetQueue;
+
+@end
190 DIYConduitBridge.m
@@ -0,0 +1,190 @@
+#import "DIYConduitBridge.h"
+
+@interface DIYConduitBridge ()
+
+@property (nonatomic,strong) NSMutableArray *startupMessageQueue;
+
+- (void)_flushMessageQueueFromWebView:(UIWebView *)webView;
+- (void)_doSendMessage:(NSString*)message toWebView:(UIWebView *)webView;
+
+@end
+
+@implementation DIYConduitBridge
+
+@synthesize delegate = _delegate;
+@synthesize startupMessageQueue = _startupMessageQueue;
+
+static NSString *MESSAGE_SEPARATOR = @"__wvjb_sep__";
+static NSString *CUSTOM_PROTOCOL_SCHEME = @"webviewjavascriptbridge";
+static NSString *QUEUE_HAS_MESSAGE = @"queuehasmessage";
+
+#pragma mark - Init
+
++ (id)javascriptBridgeWithDelegate:(id <DIYConduitBridgeDelegate>)delegate
+{
+ DIYConduitBridge* bridge = [[[DIYConduitBridge alloc] init] autorelease];
+ bridge.delegate = delegate;
+ [bridge resetQueue];
+ return bridge;
+}
+
+#pragma mark - Public methods
+
+- (void)sendMessage:(NSString *)message toWebView:(UIWebView *)webView
+{
+ if (self.startupMessageQueue) { [self.startupMessageQueue addObject:message]; }
+ else { [self _doSendMessage:message toWebView: webView]; }
+}
+
+- (void)resetQueue
+{
+ self.startupMessageQueue = [[[NSMutableArray alloc] init] autorelease];
+}
+
+- (void)_doSendMessage:(NSString *)message toWebView:(UIWebView *)webView
+{
+ message = [message stringByReplacingOccurrencesOfString:@"\\n" withString:@"\\\\n"];
+ message = [message stringByReplacingOccurrencesOfString:@"'" withString:@"\\'"];
+ message = [message stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""];
+ [webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"WebViewJavascriptBridge._handleMessageFromObjC('%@');", message]];
+}
+
+- (void)_flushMessageQueueFromWebView:(UIWebView *)webView
+{
+ NSString *messageQueueString = [webView stringByEvaluatingJavaScriptFromString:@"WebViewJavascriptBridge._fetchQueue();"];
+ NSArray* messages = [messageQueueString componentsSeparatedByString:MESSAGE_SEPARATOR];
+ for (id message in messages) {
+ [self.delegate javascriptBridge:self receivedMessage:message fromWebView:webView];
+ }
+}
+
+#pragma mark UIWebViewDelegate
+
+- (void)webViewDidFinishLoad:(UIWebView *)webView
+{
+ NSString *js = [NSString stringWithFormat:@";(function() {"
+ "if (window.WebViewJavascriptBridge) { return; };"
+ "var _readyMessageIframe,"
+ " _sendMessageQueue = [],"
+ " _receiveMessageQueue = [],"
+ " _MESSAGE_SEPERATOR = '%@',"
+ " _CUSTOM_PROTOCOL_SCHEME = '%@',"
+ " _QUEUE_HAS_MESSAGE = '%@';"
+ ""
+ "function _createQueueReadyIframe(doc) {"
+ " _readyMessageIframe = doc.createElement('iframe');"
+ " _readyMessageIframe.style.display = 'none';"
+ " doc.documentElement.appendChild(_readyMessageIframe);"
+ "}"
+ ""
+ "function _sendMessage(message) {"
+ " _sendMessageQueue.push(message);"
+ " _readyMessageIframe.src = _CUSTOM_PROTOCOL_SCHEME + '://' + _QUEUE_HAS_MESSAGE;"
+ "};"
+ ""
+ "function _fetchQueue() {"
+ " var messageQueueString = _sendMessageQueue.join(_MESSAGE_SEPERATOR);"
+ " _sendMessageQueue = [];"
+ " return messageQueueString;"
+ "};"
+ ""
+ "function _setMessageHandler(messageHandler) {"
+ " if (WebViewJavascriptBridge._messageHandler) { return alert('WebViewJavascriptBridge.setMessageHandler called twice'); }"
+ " WebViewJavascriptBridge._messageHandler = messageHandler;"
+ " var receivedMessages = _receiveMessageQueue;"
+ " _receiveMessageQueue = null;"
+ " for (var i=0; i<receivedMessages.length; i++) {"
+ " messageHandler(receivedMessages[i]);"
+ " }"
+ "};"
+ ""
+ "function _handleMessageFromObjC(message) {"
+ " if (_receiveMessageQueue) { _receiveMessageQueue.push(message); }"
+ " else { WebViewJavascriptBridge._messageHandler(message); }"
+ "};"
+ ""
+ "window.WebViewJavascriptBridge = {"
+ " setMessageHandler: _setMessageHandler,"
+ " sendMessage: _sendMessage,"
+ " _fetchQueue: _fetchQueue,"
+ " _handleMessageFromObjC: _handleMessageFromObjC"
+ "};"
+ ""
+ "var doc = document;"
+ "_createQueueReadyIframe(doc);"
+ "var readyEvent = doc.createEvent('Events');"
+ "readyEvent.initEvent('WebViewJavascriptBridgeReady');"
+ "doc.dispatchEvent(readyEvent);"
+ ""
+ "})();",
+ MESSAGE_SEPARATOR,
+ CUSTOM_PROTOCOL_SCHEME,
+ QUEUE_HAS_MESSAGE];
+
+ if (![[webView stringByEvaluatingJavaScriptFromString:@"typeof WebViewJavascriptBridge == 'object'"] isEqualToString:@"true"])
+ {
+ [webView stringByEvaluatingJavaScriptFromString:js];
+ }
+
+ for (id message in self.startupMessageQueue)
+ {
+ [self _doSendMessage:message toWebView: webView];
+ }
+
+ self.startupMessageQueue = nil;
+
+ if (self.delegate != nil && [self.delegate respondsToSelector:@selector(webViewDidFinishLoad:)])
+ {
+ [self.delegate webViewDidFinishLoad:webView];
+ }
+}
+
+- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
+{
+ if (self.delegate != nil && [self.delegate respondsToSelector:@selector(webView:didFailLoadWithError:)])
+ {
+ [self.delegate webView:webView didFailLoadWithError:error];
+ }
+}
+
+- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
+{
+ NSURL *url = [request URL];
+ if (![[url scheme] isEqualToString:CUSTOM_PROTOCOL_SCHEME])
+ {
+ if (self.delegate != nil && [self.delegate respondsToSelector:@selector(webView:shouldStartLoadWithRequest:navigationType:)])
+ {
+ return [self.delegate webView:webView shouldStartLoadWithRequest:request navigationType:navigationType];
+ }
+ return YES;
+ }
+
+ if ([[url host] isEqualToString:QUEUE_HAS_MESSAGE])
+ {
+ [self _flushMessageQueueFromWebView: webView];
+ } else {
+ NSLog(@"WebViewJavascriptBridge: WARNING: Received unknown WebViewJavascriptBridge command %@://%@", CUSTOM_PROTOCOL_SCHEME, [url path]);
+ }
+
+ return NO;
+}
+
+- (void)webViewDidStartLoad:(UIWebView *)webView
+{
+ if (self.delegate != nil && [self.delegate respondsToSelector:@selector(webViewDidStartLoad:)])
+ {
+ [self.delegate webViewDidStartLoad:webView];
+ }
+}
+
+#pragma mark - Dealloc
+
+- (void)dealloc
+{
+ _delegate = nil;
+ [_startupMessageQueue release];
+
+ [super dealloc];
+}
+
+@end
13 LICENSE.md
@@ -0,0 +1,13 @@
+Copyright 2011 DIY, Co.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
137 README.md
@@ -0,0 +1,137 @@
+## Conduit
+#### JS to Objective-C... and back again
+
+DIYConduit was created to address three pain points present within many iOS applications that rely on UIWebView to present content to the user:
+- Communication from Javascript to Objective-C
+- Communication from Objective-C to Javascript
+- Handling custom HTTP headers between multiple requests
+
+DIYConduit simply wraps these three pieces of functionality into a nice little library with a simple API and lets you go on about your business.
+
+## Basic Use
+The fastest way to get up and running with DIYConduit is to take a look at the included example application. The XCode project file can be found in "example > conduit.xcodeproj". But for those of you that put on your adventure pants today... read ahead:
+
+YourViewController.h
+```objective-c
+#import <UIKit/UIKit.h>
+#import "DIYConduit.h"
+
+@interface YourViewController : UIViewController <DIYConduitDelegate>
+@property (nonatomic, retain) IBOutlet DIYConduit *conduit;
+@end
+```
+
+YourViewController.m
+```objective-c
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ [conduit setDelegate:self];
+ [conduit loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://my.awesomecats.com/index.html"]]];
+}
+
+- (void)conduit:(DIYConduit *)conduit receivedMessage:(NSString *)message
+{
+ NSLog(@"%@", message);
+}
+```
+
+index.html
+```html
+<!doctype html>
+<html>
+ <head>
+ <style type='text/css'>body { font-family: Helvetica; } h1 { color:#333; }</style>
+ </head>
+ <body>
+ <h1>Conduit Demo</h1>
+
+ <script>
+ document.addEventListener('WebViewJavascriptBridgeReady', onBridgeReady, false);
+ function onBridgeReady() {
+ WebViewJavascriptBridge.setMessageHandler(function(message) {
+ var el = document.body.appendChild(document.createElement('div'));
+ el.innerHTML = message;
+ });
+
+ WebViewJavascriptBridge.sendMessage('hello from the JS');
+ var button = document.body.appendChild(document.createElement('button'));
+ button.innerHTML = 'Click me to send a message to ObjC';
+ button.onclick = button.ontouchup = function() { WebViewJavascriptBridge.sendMessage('hello from JS button'); };
+ }
+ </script>
+ </body>
+</html>
+```
+
+## JS to Objective-C
+Communication from JS to Objective-C is handled by the "sendMessage" function on the WebViewJavascriptBridge object. The function should only be called after the "WebViewJavascriptBridgeReady" event.
+```javascript
+document.addEventListener('WebViewJavascriptBridgeReady', onBridgeReady, false);
+function onBridgeReady() {
+ WebViewJavascriptBridge.sendMessage('Hello from the magical land of Javascript. Unicorns! Rainbows! Substack!');
+}
+```
+
+Receipt of messages from JS is handled through the use of a delegate method.
+```objective-c
+- (void)conduit:(DIYConduit *)conduit receivedMessage:(NSString *)message
+{
+ NSLog(@"%@", message);
+}
+```
+
+## Objective-C to JS
+Communication from Objective-C to JS is handled by the "sendMessage" method. This method can be invoked at any time though messages will be queued until received by the web view.
+```objective-c
+[conduit sendMessage:@"Hello from Objective-C. *Beep* *Buzz* ... *Ding!*"];
+```
+
+Similar to how messages are sent from JS, messages are received after the "WebViewJavascriptBridgeReady" has been called via the "setMessageHandler" function.
+```javascript
+document.addEventListener('WebViewJavascriptBridgeReady', onBridgeReady, false);
+function onBridgeReady() {
+ WebViewJavascriptBridge.setMessageHandler(function (message) {
+ alert(message);
+ });
+}
+```
+
+## Custom HTTP Headers
+Custom headers can be a bit of a pain when using a vanilla UIWebView, so DIYConduit provides convience methods for creating and removing custom headers while persisting them through requests. Headers can be added and removed at will and will immediately reflected and persisted starting with the next HTTP request.
+
+```objective-c
+[conduit addHeader:@"x-some-header" withValue:@"foo"];
+[conduit removeHeader:@"x-something-else"];
+```
+
+---
+
+## Methods
+```objective-c
+- (void)loadRequest:(NSURLRequest *)request;
+- (void)loadHTMLString:(NSString *)html baseURL:(NSURL *)baseURL;
+- (void)addHeader:(NSString *)key withValue:(NSString *)value;
+- (void)removeHeader:(NSString *)key;
+- (void)sendMessage:(NSString *)message;
+- (void)resetMessageQueue;
+```
+
+## Delegate Methods
+```objective-c
+- (void)conduit:(DIYConduit *)conduit receivedMessage:(NSString *)message;
+```
+
+## Properites
+```objective-c
+@property (nonatomic, assign) id <DIYConduitDelegate> delegate;
+@property (nonatomic, retain) UIWebView *webView;
+@property (nonatomic, retain) NSMutableDictionary *headers;
+```
+
+## ARC
+ARC is not supported at this time. It is most certainly on the big 'ol "to-do" list though.
+
+## Credits
+Conduit's Objective-C to JS bridge is based on [WebViewJavascriptBridge](https://github.com/marcuswestin/WebViewJavascriptBridge) by Marcus Westin, Stepan Generalov and Sergio Campamá.
474 example/conduit.xcodeproj/project.pbxproj
@@ -0,0 +1,474 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ C3AF160D158E752D00EA444D /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3AF160C158E752D00EA444D /* UIKit.framework */; };
+ C3AF160F158E752D00EA444D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3AF160E158E752D00EA444D /* Foundation.framework */; };
+ C3AF1611158E752D00EA444D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3AF1610158E752D00EA444D /* CoreGraphics.framework */; };
+ C3AF1617158E752D00EA444D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = C3AF1615158E752D00EA444D /* InfoPlist.strings */; };
+ C3AF1619158E752D00EA444D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C3AF1618158E752D00EA444D /* main.m */; };
+ C3AF161D158E752D00EA444D /* DIYAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = C3AF161C158E752D00EA444D /* DIYAppDelegate.m */; };
+ C3AF1620158E752D00EA444D /* DIYViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C3AF161F158E752D00EA444D /* DIYViewController.m */; };
+ C3AF1623158E752D00EA444D /* DIYViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = C3AF1621158E752D00EA444D /* DIYViewController.xib */; };
+ C3AF162B158E752D00EA444D /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3AF162A158E752D00EA444D /* SenTestingKit.framework */; };
+ C3AF162C158E752D00EA444D /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3AF160C158E752D00EA444D /* UIKit.framework */; };
+ C3AF162D158E752D00EA444D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3AF160E158E752D00EA444D /* Foundation.framework */; };
+ C3AF1635158E752D00EA444D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = C3AF1633158E752D00EA444D /* InfoPlist.strings */; };
+ C3AF1638158E752D00EA444D /* conduitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C3AF1637158E752D00EA444D /* conduitTests.m */; };
+ C3AF1647158E766100EA444D /* DIYConduit.m in Sources */ = {isa = PBXBuildFile; fileRef = C3AF1646158E766100EA444D /* DIYConduit.m */; };
+ C3AF1649158E7A0100EA444D /* DIYConduit.m in Sources */ = {isa = PBXBuildFile; fileRef = C3AF1646158E766100EA444D /* DIYConduit.m */; };
+ C3AF1650158EA1F100EA444D /* DIYConduitBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = C3AF164F158EA1F100EA444D /* DIYConduitBridge.m */; };
+ C3AF1652158EC4A800EA444D /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = C3AF1651158EC4A800EA444D /* README.md */; };
+ C3AF1654158EC4BA00EA444D /* LICENSE.md in Resources */ = {isa = PBXBuildFile; fileRef = C3AF1653158EC4BA00EA444D /* LICENSE.md */; };
+ C3AF1655158ED61000EA444D /* DIYConduitBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = C3AF164F158EA1F100EA444D /* DIYConduitBridge.m */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ C3AF162E158E752D00EA444D /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = C3AF15FF158E752C00EA444D /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = C3AF1607158E752D00EA444D;
+ remoteInfo = conduit;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ C3AF1608158E752D00EA444D /* conduit.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = conduit.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ C3AF160C158E752D00EA444D /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
+ C3AF160E158E752D00EA444D /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+ C3AF1610158E752D00EA444D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
+ C3AF1614158E752D00EA444D /* conduit-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "conduit-Info.plist"; sourceTree = "<group>"; };
+ C3AF1616158E752D00EA444D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+ C3AF1618158E752D00EA444D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+ C3AF161A158E752D00EA444D /* conduit-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "conduit-Prefix.pch"; sourceTree = "<group>"; };
+ C3AF161B158E752D00EA444D /* DIYAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DIYAppDelegate.h; sourceTree = "<group>"; };
+ C3AF161C158E752D00EA444D /* DIYAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DIYAppDelegate.m; sourceTree = "<group>"; };
+ C3AF161E158E752D00EA444D /* DIYViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DIYViewController.h; sourceTree = "<group>"; };
+ C3AF161F158E752D00EA444D /* DIYViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DIYViewController.m; sourceTree = "<group>"; };
+ C3AF1622158E752D00EA444D /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/DIYViewController.xib; sourceTree = "<group>"; };
+ C3AF1629158E752D00EA444D /* conduitTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = conduitTests.octest; sourceTree = BUILT_PRODUCTS_DIR; };
+ C3AF162A158E752D00EA444D /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; };
+ C3AF1632158E752D00EA444D /* conduitTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "conduitTests-Info.plist"; sourceTree = "<group>"; };
+ C3AF1634158E752D00EA444D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+ C3AF1636158E752D00EA444D /* conduitTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = conduitTests.h; sourceTree = "<group>"; };
+ C3AF1637158E752D00EA444D /* conduitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = conduitTests.m; sourceTree = "<group>"; };
+ C3AF1645158E766100EA444D /* DIYConduit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DIYConduit.h; path = ../DIYConduit.h; sourceTree = "<group>"; };
+ C3AF1646158E766100EA444D /* DIYConduit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DIYConduit.m; path = ../DIYConduit.m; sourceTree = "<group>"; };
+ C3AF164E158EA1F100EA444D /* DIYConduitBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DIYConduitBridge.h; path = ../DIYConduitBridge.h; sourceTree = "<group>"; };
+ C3AF164F158EA1F100EA444D /* DIYConduitBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DIYConduitBridge.m; path = ../DIYConduitBridge.m; sourceTree = "<group>"; };
+ C3AF1651158EC4A800EA444D /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = README.md; path = ../README.md; sourceTree = "<group>"; };
+ C3AF1653158EC4BA00EA444D /* LICENSE.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = LICENSE.md; path = ../LICENSE.md; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ C3AF1605158E752D00EA444D /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ C3AF160D158E752D00EA444D /* UIKit.framework in Frameworks */,
+ C3AF160F158E752D00EA444D /* Foundation.framework in Frameworks */,
+ C3AF1611158E752D00EA444D /* CoreGraphics.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ C3AF1625158E752D00EA444D /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ C3AF162B158E752D00EA444D /* SenTestingKit.framework in Frameworks */,
+ C3AF162C158E752D00EA444D /* UIKit.framework in Frameworks */,
+ C3AF162D158E752D00EA444D /* Foundation.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ C3AF15FD158E752C00EA444D = {
+ isa = PBXGroup;
+ children = (
+ C3AF1645158E766100EA444D /* DIYConduit.h */,
+ C3AF1646158E766100EA444D /* DIYConduit.m */,
+ C3AF164E158EA1F100EA444D /* DIYConduitBridge.h */,
+ C3AF164F158EA1F100EA444D /* DIYConduitBridge.m */,
+ C3AF1651158EC4A800EA444D /* README.md */,
+ C3AF1653158EC4BA00EA444D /* LICENSE.md */,
+ C3AF1612158E752D00EA444D /* conduit */,
+ C3AF1630158E752D00EA444D /* conduitTests */,
+ C3AF160B158E752D00EA444D /* Frameworks */,
+ C3AF1609158E752D00EA444D /* Products */,
+ );
+ sourceTree = "<group>";
+ };
+ C3AF1609158E752D00EA444D /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ C3AF1608158E752D00EA444D /* conduit.app */,
+ C3AF1629158E752D00EA444D /* conduitTests.octest */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ C3AF160B158E752D00EA444D /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ C3AF160C158E752D00EA444D /* UIKit.framework */,
+ C3AF160E158E752D00EA444D /* Foundation.framework */,
+ C3AF1610158E752D00EA444D /* CoreGraphics.framework */,
+ C3AF162A158E752D00EA444D /* SenTestingKit.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+ C3AF1612158E752D00EA444D /* conduit */ = {
+ isa = PBXGroup;
+ children = (
+ C3AF161B158E752D00EA444D /* DIYAppDelegate.h */,
+ C3AF161C158E752D00EA444D /* DIYAppDelegate.m */,
+ C3AF161E158E752D00EA444D /* DIYViewController.h */,
+ C3AF161F158E752D00EA444D /* DIYViewController.m */,
+ C3AF1621158E752D00EA444D /* DIYViewController.xib */,
+ C3AF1613158E752D00EA444D /* Supporting Files */,
+ );
+ path = conduit;
+ sourceTree = "<group>";
+ };
+ C3AF1613158E752D00EA444D /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ C3AF1614158E752D00EA444D /* conduit-Info.plist */,
+ C3AF1615158E752D00EA444D /* InfoPlist.strings */,
+ C3AF1618158E752D00EA444D /* main.m */,
+ C3AF161A158E752D00EA444D /* conduit-Prefix.pch */,
+ );
+ name = "Supporting Files";
+ sourceTree = "<group>";
+ };
+ C3AF1630158E752D00EA444D /* conduitTests */ = {
+ isa = PBXGroup;
+ children = (
+ C3AF1636158E752D00EA444D /* conduitTests.h */,
+ C3AF1637158E752D00EA444D /* conduitTests.m */,
+ C3AF1631158E752D00EA444D /* Supporting Files */,
+ );
+ path = conduitTests;
+ sourceTree = "<group>";
+ };
+ C3AF1631158E752D00EA444D /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ C3AF1632158E752D00EA444D /* conduitTests-Info.plist */,
+ C3AF1633158E752D00EA444D /* InfoPlist.strings */,
+ );
+ name = "Supporting Files";
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ C3AF1607158E752D00EA444D /* conduit */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = C3AF163B158E752D00EA444D /* Build configuration list for PBXNativeTarget "conduit" */;
+ buildPhases = (
+ C3AF1604158E752D00EA444D /* Sources */,
+ C3AF1605158E752D00EA444D /* Frameworks */,
+ C3AF1606158E752D00EA444D /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = conduit;
+ productName = conduit;
+ productReference = C3AF1608158E752D00EA444D /* conduit.app */;
+ productType = "com.apple.product-type.application";
+ };
+ C3AF1628158E752D00EA444D /* conduitTests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = C3AF163E158E752D00EA444D /* Build configuration list for PBXNativeTarget "conduitTests" */;
+ buildPhases = (
+ C3AF1624158E752D00EA444D /* Sources */,
+ C3AF1625158E752D00EA444D /* Frameworks */,
+ C3AF1626158E752D00EA444D /* Resources */,
+ C3AF1627158E752D00EA444D /* ShellScript */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ C3AF162F158E752D00EA444D /* PBXTargetDependency */,
+ );
+ name = conduitTests;
+ productName = conduitTests;
+ productReference = C3AF1629158E752D00EA444D /* conduitTests.octest */;
+ productType = "com.apple.product-type.bundle";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ C3AF15FF158E752C00EA444D /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ CLASSPREFIX = DIY;
+ LastUpgradeCheck = 0430;
+ ORGANIZATIONNAME = "DIY, Co.";
+ };
+ buildConfigurationList = C3AF1602158E752C00EA444D /* Build configuration list for PBXProject "conduit" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ );
+ mainGroup = C3AF15FD158E752C00EA444D;
+ productRefGroup = C3AF1609158E752D00EA444D /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ C3AF1607158E752D00EA444D /* conduit */,
+ C3AF1628158E752D00EA444D /* conduitTests */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ C3AF1606158E752D00EA444D /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ C3AF1617158E752D00EA444D /* InfoPlist.strings in Resources */,
+ C3AF1623158E752D00EA444D /* DIYViewController.xib in Resources */,
+ C3AF1652158EC4A800EA444D /* README.md in Resources */,
+ C3AF1654158EC4BA00EA444D /* LICENSE.md in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ C3AF1626158E752D00EA444D /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ C3AF1635158E752D00EA444D /* InfoPlist.strings in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ C3AF1627158E752D00EA444D /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n";
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ C3AF1604158E752D00EA444D /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ C3AF1619158E752D00EA444D /* main.m in Sources */,
+ C3AF161D158E752D00EA444D /* DIYAppDelegate.m in Sources */,
+ C3AF1620158E752D00EA444D /* DIYViewController.m in Sources */,
+ C3AF1647158E766100EA444D /* DIYConduit.m in Sources */,
+ C3AF1650158EA1F100EA444D /* DIYConduitBridge.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ C3AF1624158E752D00EA444D /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ C3AF1655158ED61000EA444D /* DIYConduitBridge.m in Sources */,
+ C3AF1649158E7A0100EA444D /* DIYConduit.m in Sources */,
+ C3AF1638158E752D00EA444D /* conduitTests.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ C3AF162F158E752D00EA444D /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = C3AF1607158E752D00EA444D /* conduit */;
+ targetProxy = C3AF162E158E752D00EA444D /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+ C3AF1615158E752D00EA444D /* InfoPlist.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ C3AF1616158E752D00EA444D /* en */,
+ );
+ name = InfoPlist.strings;
+ sourceTree = "<group>";
+ };
+ C3AF1621158E752D00EA444D /* DIYViewController.xib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ C3AF1622158E752D00EA444D /* en */,
+ );
+ name = DIYViewController.xib;
+ sourceTree = "<group>";
+ };
+ C3AF1633158E752D00EA444D /* InfoPlist.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ C3AF1634158E752D00EA444D /* en */,
+ );
+ name = InfoPlist.strings;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ C3AF1639158E752D00EA444D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 5.1;
+ SDKROOT = iphoneos;
+ };
+ name = Debug;
+ };
+ C3AF163A158E752D00EA444D /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 5.1;
+ OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
+ SDKROOT = iphoneos;
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ C3AF163C158E752D00EA444D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "conduit/conduit-Prefix.pch";
+ INFOPLIST_FILE = "conduit/conduit-Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 4.3;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ WRAPPER_EXTENSION = app;
+ };
+ name = Debug;
+ };
+ C3AF163D158E752D00EA444D /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "conduit/conduit-Prefix.pch";
+ INFOPLIST_FILE = "conduit/conduit-Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 4.3;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ WRAPPER_EXTENSION = app;
+ };
+ name = Release;
+ };
+ C3AF163F158E752D00EA444D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/conduit.app/conduit";
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(SDKROOT)/Developer/Library/Frameworks",
+ "$(DEVELOPER_LIBRARY_DIR)/Frameworks",
+ );
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "conduit/conduit-Prefix.pch";
+ INFOPLIST_FILE = "conduitTests/conduitTests-Info.plist";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TEST_AFTER_BUILD = YES;
+ TEST_HOST = "";
+ WRAPPER_EXTENSION = octest;
+ };
+ name = Debug;
+ };
+ C3AF1640158E752D00EA444D /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/conduit.app/conduit";
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(SDKROOT)/Developer/Library/Frameworks",
+ "$(DEVELOPER_LIBRARY_DIR)/Frameworks",
+ );
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "conduit/conduit-Prefix.pch";
+ INFOPLIST_FILE = "conduitTests/conduitTests-Info.plist";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TEST_AFTER_BUILD = YES;
+ TEST_HOST = "";
+ WRAPPER_EXTENSION = octest;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ C3AF1602158E752C00EA444D /* Build configuration list for PBXProject "conduit" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C3AF1639158E752D00EA444D /* Debug */,
+ C3AF163A158E752D00EA444D /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ C3AF163B158E752D00EA444D /* Build configuration list for PBXNativeTarget "conduit" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C3AF163C158E752D00EA444D /* Debug */,
+ C3AF163D158E752D00EA444D /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ C3AF163E158E752D00EA444D /* Build configuration list for PBXNativeTarget "conduitTests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C3AF163F158E752D00EA444D /* Debug */,
+ C3AF1640158E752D00EA444D /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = C3AF15FF158E752C00EA444D /* Project object */;
+}
7 example/conduit.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+ version = "1.0">
+ <FileRef
+ location = "self:conduit.xcodeproj">
+ </FileRef>
+</Workspace>
18 example/conduit/DIYAppDelegate.h
@@ -0,0 +1,18 @@
+//
+// DIYAppDelegate.h
+// conduit
+//
+// Created by Andrew Sliwinski on 6/17/12.
+// Copyright (c) 2012 DIY, Co. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@class DIYViewController;
+
+@interface DIYAppDelegate : UIResponder <UIApplicationDelegate>
+
+@property (strong, nonatomic) UIWindow *window;
+@property (strong, nonatomic) DIYViewController *viewController;
+
+@end
66 example/conduit/DIYAppDelegate.m
@@ -0,0 +1,66 @@
+//
+// DIYAppDelegate.m
+// conduit
+//
+// Created by Andrew Sliwinski on 6/17/12.
+// Copyright (c) 2012 DIY, Co. All rights reserved.
+//
+
+#import "DIYAppDelegate.h"
+#import "DIYViewController.h"
+
+@implementation DIYAppDelegate
+
+@synthesize window = _window;
+@synthesize viewController = _viewController;
+
+- (void)dealloc
+{
+ [_window release];
+ [_viewController release];
+ [super dealloc];
+}
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
+{
+ self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
+
+ //
+
+ //
+
+ self.viewController = [[[DIYViewController alloc] initWithNibName:@"DIYViewController" bundle:nil] autorelease];
+ self.window.rootViewController = self.viewController;
+ [self.window makeKeyAndVisible];
+
+ return true;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application
+{
+ // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application
+{
+ // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application
+{
+ // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application
+{
+ // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application
+{
+ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+@end
19 example/conduit/DIYViewController.h
@@ -0,0 +1,19 @@
+//
+// DIYViewController.h
+// conduit
+//
+// Created by Andrew Sliwinski on 6/17/12.
+// Copyright (c) 2012 DIY, Co. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+#import "DIYConduit.h"
+
+@interface DIYViewController : UIViewController <DIYConduitDelegate>
+
+@property (nonatomic, retain) IBOutlet DIYConduit *conduit;
+@property (nonatomic, retain) IBOutlet UIButton *objcToJsButton;
+
+- (IBAction)sendMessage:(id)sender;
+
+@end
97 example/conduit/DIYViewController.m
@@ -0,0 +1,97 @@
+//
+// DIYViewController.m
+// conduit
+//
+// Created by Andrew Sliwinski on 6/17/12.
+// Copyright (c) 2012 DIY, Co. All rights reserved.
+//
+
+#import "DIYViewController.h"
+
+@implementation DIYViewController
+
+@synthesize conduit;
+@synthesize objcToJsButton;
+
+#pragma mark - View lifecycle
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ //
+
+ [conduit setDelegate:self];
+ [conduit addHeader:@"x-some-header" withValue:@"foo"];
+ [conduit removeHeader:@"x-some-other-header"];
+ [conduit loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://my.awesomecat.com/"]]];
+
+ [self renderWebView];
+}
+
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
+{
+ return (interfaceOrientation == UIInterfaceOrientationPortrait);
+}
+
+#pragma mark - Render
+
+- (void)renderWebView
+{
+ [conduit loadHTMLString:@""
+ "<!doctype html>"
+ "<html><head>"
+ " <style type='text/css'>body { font-family: Helvetica; } h1 { color:#333; }</style>"
+ "</head><body>"
+ " <h1>Conduit Demo</h1>"
+ " <script>"
+ " document.addEventListener('WebViewJavascriptBridgeReady', onBridgeReady, false);"
+ " function onBridgeReady() {"
+ " WebViewJavascriptBridge.setMessageHandler(function(message) {"
+ " var el = document.body.appendChild(document.createElement('div'));"
+ " el.innerHTML = message;"
+ " });"
+ " WebViewJavascriptBridge.sendMessage('hello from the JS');"
+ " var button = document.body.appendChild(document.createElement('button'));"
+ " button.innerHTML = 'Click me to send a message to ObjC';"
+ " button.onclick = button.ontouchup = function() { WebViewJavascriptBridge.sendMessage('hello from JS button'); };"
+ " }"
+ " </script>"
+ "</body></html>" baseURL:nil];
+}
+
+#pragma mark - UI events
+
+- (IBAction)sendMessage:(id)sender
+{
+ [conduit sendMessage:@"hello from Objective-C button"];
+}
+
+#pragma mark - Conduit Delegate
+
+- (void)conduit:(DIYConduit *)conduit receivedMessage:(NSString *)message
+{
+ NSLog(@"%@", message);
+}
+
+#pragma mark - Dealloc
+
+- (void)releaseObjects
+{
+ [conduit release]; conduit = nil;
+ [objcToJsButton release]; objcToJsButton = nil;
+}
+
+- (void)viewDidUnload
+{
+ [super viewDidUnload];
+ [self releaseObjects];
+}
+
+- (void)dealloc
+{
+ [self releaseObjects];
+ [super dealloc];
+}
+
+@end
36 example/conduit/conduit-Info.plist
@@ -0,0 +1,36 @@
+<?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>${PRODUCT_NAME}</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.diy.${PRODUCT_NAME:rfc1034identifier}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>LSRequiresIPhoneOS</key>
+ <true/>
+ <key>UIRequiredDeviceCapabilities</key>
+ <array>
+ <string>armv7</string>
+ </array>
+ <key>UISupportedInterfaceOrientations</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ </array>
+</dict>
+</plist>
14 example/conduit/conduit-Prefix.pch
@@ -0,0 +1,14 @@
+//
+// Prefix header for all source files of the 'conduit' target in the 'conduit' project
+//
+
+#import <Availability.h>
+
+#ifndef __IPHONE_4_0
+#warning "This project uses features only available in iOS SDK 4.0 and later."
+#endif
+
+#ifdef __OBJC__
+ #import <UIKit/UIKit.h>
+ #import <Foundation/Foundation.h>
+#endif
254 example/conduit/en.lproj/DIYViewController.xib
@@ -0,0 +1,254 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
+ <data>
+ <int key="IBDocument.SystemTarget">1296</int>
+ <string key="IBDocument.SystemVersion">11D50b</string>
+ <string key="IBDocument.InterfaceBuilderVersion">2182</string>
+ <string key="IBDocument.AppKitVersion">1138.32</string>
+ <string key="IBDocument.HIToolboxVersion">568.00</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="NS.object.0">1181</string>
+ </object>
+ <array key="IBDocument.IntegratedClassDependencies">
+ <string>IBProxyObject</string>
+ <string>IBUIView</string>
+ <string>IBUIButton</string>
+ </array>
+ <array key="IBDocument.PluginDependencies">
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </array>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <string key="NS.key.0">PluginDependencyRecalculationVersion</string>
+ <integer value="1" key="NS.object.0"/>
+ </object>
+ <array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+ <object class="IBProxyObject" id="372490531">
+ <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBProxyObject" id="843779117">
+ <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBUIView" id="774585933">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">274</int>
+ <array class="NSMutableArray" key="NSSubviews">
+ <object class="IBUIView" id="1006630648">
+ <reference key="NSNextResponder" ref="774585933"/>
+ <int key="NSvFlags">274</int>
+ <string key="NSFrameSize">{320, 460}</string>
+ <reference key="NSSuperview" ref="774585933"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="203106896"/>
+ <string key="NSReuseIdentifierKey">_NS:9</string>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ <object class="NSColorSpace" key="NSCustomColorSpace" id="858759279">
+ <int key="NSID">2</int>
+ </object>
+ </object>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBUIButton" id="203106896">
+ <reference key="NSNextResponder" ref="774585933"/>
+ <int key="NSvFlags">292</int>
+ <string key="NSFrame">{{20, 403}, {280, 37}}</string>
+ <reference key="NSSuperview" ref="774585933"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView"/>
+ <string key="NSReuseIdentifierKey">_NS:9</string>
+ <bool key="IBUIOpaque">NO</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <int key="IBUIContentHorizontalAlignment">0</int>
+ <int key="IBUIContentVerticalAlignment">0</int>
+ <int key="IBUIButtonType">1</int>
+ <string key="IBUINormalTitle">Click me to send a message to JS</string>
+ <object class="NSColor" key="IBUIHighlightedTitleColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ </object>
+ <object class="NSColor" key="IBUINormalTitleColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
+ </object>
+ <object class="NSColor" key="IBUINormalTitleShadowColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MC41AA</bytes>
+ </object>
+ <object class="IBUIFontDescription" key="IBUIFontDescription">
+ <int key="type">2</int>
+ <double key="pointSize">15</double>
+ </object>
+ <object class="NSFont" key="IBUIFont">
+ <string key="NSName">Helvetica-Bold</string>
+ <double key="NSSize">15</double>
+ <int key="NSfFlags">16</int>
+ </object>
+ </object>
+ </array>
+ <string key="NSFrame">{{0, 20}, {320, 460}}</string>
+ <reference key="NSSuperview"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="1006630648"/>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MC43NQA</bytes>
+ <reference key="NSCustomColorSpace" ref="858759279"/>
+ </object>
+ <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+ <object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ </array>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <array class="NSMutableArray" key="connectionRecords">
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">view</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="774585933"/>
+ </object>
+ <int key="connectionID">7</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">conduit</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="1006630648"/>
+ </object>
+ <int key="connectionID">10</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">objcToJsButton</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="203106896"/>
+ </object>
+ <int key="connectionID">11</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">sendMessage:</string>
+ <reference key="source" ref="203106896"/>
+ <reference key="destination" ref="372490531"/>
+ <int key="IBEventType">7</int>
+ </object>
+ <int key="connectionID">12</int>
+ </object>
+ </array>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <array key="orderedObjects">
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <array key="object" id="0"/>
+ <reference key="children" ref="1000"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="372490531"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">File's Owner</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="843779117"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">6</int>
+ <reference key="object" ref="774585933"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="1006630648"/>
+ <reference ref="203106896"/>
+ </array>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">8</int>
+ <reference key="object" ref="1006630648"/>
+ <array class="NSMutableArray" key="children"/>
+ <reference key="parent" ref="774585933"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">9</int>
+ <reference key="object" ref="203106896"/>
+ <reference key="parent" ref="774585933"/>
+ </object>
+ </array>
+ </object>
+ <dictionary class="NSMutableDictionary" key="flattenedProperties">
+ <string key="-1.CustomClassName">DIYViewController</string>
+ <string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="-2.CustomClassName">UIResponder</string>
+ <string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="6.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="8.CustomClassName">DIYConduit</string>
+ <string key="8.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="9.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </dictionary>
+ <dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
+ <nil key="activeLocalization"/>
+ <dictionary class="NSMutableDictionary" key="localizations"/>
+ <nil key="sourceID"/>
+ <int key="maxID">12</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <array class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <object class="IBPartialClassDescription">
+ <string key="className">DIYConduit</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/DIYConduit.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">DIYViewController</string>
+ <string key="superclassName">UIViewController</string>
+ <object class="NSMutableDictionary" key="actions">
+ <string key="NS.key.0">sendMessage:</string>
+ <string key="NS.object.0">id</string>
+ </object>
+ <object class="NSMutableDictionary" key="actionInfosByName">
+ <string key="NS.key.0">sendMessage:</string>
+ <object class="IBActionInfo" key="NS.object.0">
+ <string key="name">sendMessage:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </object>
+ <dictionary class="NSMutableDictionary" key="outlets">
+ <string key="conduit">DIYConduit</string>
+ <string key="objcToJsButton">UIButton</string>
+ </dictionary>
+ <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <object class="IBToOneOutletInfo" key="conduit">
+ <string key="name">conduit</string>
+ <string key="candidateClassName">DIYConduit</string>
+ </object>
+ <object class="IBToOneOutletInfo" key="objcToJsButton">
+ <string key="name">objcToJsButton</string>
+ <string key="candidateClassName">UIButton</string>
+ </object>
+ </dictionary>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/DIYViewController.h</string>
+ </object>
+ </object>
+ </array>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+ <real value="1296" key="NS.object.0"/>
+ </object>
+ <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ <string key="IBCocoaTouchPluginVersion">1181</string>
+ </data>
+</archive>
2 example/conduit/en.lproj/InfoPlist.strings
@@ -0,0 +1,2 @@
+/* Localized versions of Info.plist keys */
+
18 example/conduit/main.m
@@ -0,0 +1,18 @@
+//
+// main.m
+// conduit
+//
+// Created by Andrew Sliwinski on 6/17/12.
+// Copyright (c) 2012 DIY, Co. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+#import "DIYAppDelegate.h"
+
+int main(int argc, char *argv[])
+{
+ @autoreleasepool {
+ return UIApplicationMain(argc, argv, nil, NSStringFromClass([DIYAppDelegate class]));
+ }
+}
22 example/conduitTests/conduitTests-Info.plist
@@ -0,0 +1,22 @@
+<?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>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.diy.${PRODUCT_NAME:rfc1034identifier}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+</dict>
+</plist>
16 example/conduitTests/conduitTests.h
@@ -0,0 +1,16 @@
+//
+// conduitTests.h
+// conduitTests
+//
+// Created by Andrew Sliwinski on 6/17/12.
+// Copyright (c) 2012 DIY, Co. All rights reserved.
+//
+
+#import <SenTestingKit/SenTestingKit.h>
+#import "DIYConduit.h"
+
+@interface conduitTests : SenTestCase
+
+@property (nonatomic, retain) DIYConduit *conduit;
+
+@end
36 example/conduitTests/conduitTests.m
@@ -0,0 +1,36 @@
+//
+// conduitTests.m
+// conduitTests
+//
+// Created by Andrew Sliwinski on 6/17/12.
+// Copyright (c) 2012 DIY, Co. All rights reserved.
+//
+
+#import "conduitTests.h"
+
+@implementation conduitTests
+
+@synthesize conduit;
+
+#pragma mark - Init
+
+- (void)setUp
+{
+ [super setUp];
+}
+
+- (void)tearDown
+{
+ [conduit release]; conduit = nil;
+
+ [super tearDown];
+}
+
+#pragma mark - Suite
+
+- (void)testInstance
+{
+ STAssertNil(nil, nil);
+}
+
+@end
2 example/conduitTests/en.lproj/InfoPlist.strings
@@ -0,0 +1,2 @@
+/* Localized versions of Info.plist keys */
+

0 comments on commit b3f3604

Please sign in to comment.