Wijourno
Wijourno is a way to connect between your Mac and your iOS devices using Bonjour! You can grab the source on GitHub here. We use GCDAsyncSockets to handle the network communication, it rocks.Delegate Methods
- (void) didReadCommand:(NSString *)command dictionary:(NSDictionary *)dictionary isServer:(BOOL)isServer;
Called whenever Wijourno read a command.Usually the NSString *command is shared between the server and client Wijourno_tags.h.
The NSDictionary *dictionary contains all of the keys and values that was sent. For now, all of the values are NSStrings, but it is easy to convert from NSString to NSNumber and other various datatypes.
The BOOL isServer is YES if the current instance of Wijourno is the server, and NO if it is the client.
- (void) connectionStarted:(NSString *)host;
Called when the connection started, with a NSString to who it is connected to.
- (void) connectionFinished:(NSString *)details;
Called when the connection finished, with details as to why it finished.
- (void) readTimedOut;
Called when the read has timed out. If this does happen, it is best to show a connection interrupted view to alert the user.Server
AppDelegate.h
Import Wijourno.h:
#import "Wijourno.h"
Implement WijournoDelegate:
@interface AppDelegate : NSObject <NSApplicationDelegate, WijournoDelegate>
Add in the variables:
Wijourno *wijourno;
NSMutableDictionary *setupDict;
...
@property (nonatomic, retain) NSMutableDictionary *setupDict;
AppDelegate.m
TopImport and declare the service name (this should be the same on the server and client)
#import "Wijourno_tags.h"
#define SERVICE_NAME @"YourAppNameForArduino"
deallocSafely disconnect and release wijourno
[wijourno closeSocket];
[wijourno release];
applicationShouldTerminate:Safely disconnect wijourno
[wijourno closeSocket];
applicationDidFinishLaunchingSet up Wijourno with your service and server name
NSMutableDictionary *serverInfo = [[NSMutableDictionary alloc] initWithCapacity:1];
[serverInfo setObject:@"MetersServer" forKey:@"name"];
wijourno = [[Wijourno alloc] init];
wijourno.delegate = self;
[wijourno initServerWithServiceName:SERVICE_NAME dictionary:serverInfo];
[serverInfo release];
connectPressedThis is when you first connect to the Arduino through Matatino (ie: the GO button). We send the setup dictionary to wijourno. This is the same for pressing stop as well, but the setup dictionary will evidently be reset to its default values.
[wijourno sendCommand:SETUP dictionary:setupDict];
receivedString (Matatino delegate method)Receive some data from the Arduino, send it to Wijourno
[wijourno sendCommand:TEXT dictionary:meterDict];
portClosed (Matatino delegate method)Port closed, reset the setup dictionary, send it
[wijourno sendCommand:SETUP dictionary:setupDict];
didReadCommand (Wijourno delegate method)Send the setup dictionary specifically to the client
if([command isEqualToString:DATA]) {
NSString *clientName = [dictionary objectForKey:@"name"];
[wijourno sendCommand:SETUP dictionary:setupDict toClient:clientName];
}
Client
AppDelegate.h
Import Wijourno.h:
#import "Wijourno.h"
Implement WijournoDelegate:
@interface AppDelegate : UIResponder <UIApplicationDelegate, WijournoDelegate>
Add in the variables:
Wijourno *wijourno;
NSDictionary *givenSetupDict;
...
@property (nonatomic, retain) NSDictionary *givenSetupDict;
AppDelegate.m
TopImport the tags
#import "Wijourno_tags.h"
deallocSafely disconnect and release wijourno
[wijourno closeSocket];
[wijourno release];
application:didFinishLaunchingWithOptions:Set up our flags, init Wijourno, wait two seconds, then check the connection (makes it seem less "clunky")
// Various BOOLs that make life easier
connVCVisible = NO;
readTimed = NO;
waitingForTimer = YES;
// Init the client
wijourno = [[Wijourno alloc] init];
wijourno.delegate = self;
[wijourno initClientWithServiceName:SERVICE_NAME dictionary:clientInfo];
// Check the connection a littler later
[NSTimer scheduledTimerWithTimeInterval:2
target:self
selector:@selector(checkConn)
userInfo:nil
repeats:NO];
checkConn:Check to see if wijourno is connected, and see if the Arduino is connected
- (void) checkConn {
if(![wijourno currentlyConnected]) {
// Show a connection view controller here, say it's searching for the connection
} else {
if([[self.givenSetupDict objectForKey:@"ArduinoConnected"] intValue] == 1) {
// Hide the connection view controller (if it is visible)
} else {
// Show the connection view controller, say it's waiting for arduino
}
}
waitingForTimer = NO;
}
applicationWillResignActiveSet a flag to let us know that the app is sleeping, and disconnect the client
sleeping = YES;
[wijourno disconnectClient];
applicationDidBecomeActiveIf it was sleeping, reconnect and in 2 seconds check the connection
if(sleeping) {
waitingForTimer = YES;
[NSTimer scheduledTimerWithTimeInterval:2
target:self
selector:@selector(checkConn)
userInfo:nil
repeats:NO];
[wijourno reconnectClient];
sleeping = NO;
}
applicationWillTerminateDisconnect the client
sleeping = YES;
[wijourno disconnectClient];
connectionFinished (Wijourno delegate method)Show that the client is searching for a connection (usually display a view here)
// Display a view that the client is now searching for a connection
readTimedOut (Wijourno delegate method)Show that the connection was interrupted (usually display a view here)
if([[self.givenSetupDict objectForKey:@"ArduinoConnected"] intValue] == 1) {
// Display a view that the connection was interrupted
readTimed = YES;
}
didReadCommand (Wijourno delegate method)We received some data! Woohoo! Let's do something with it depending on what it is...
if(readTimed && connVCVisible) {
readTimed = NO;
// Hide the view that was saying the connection was interrupted
}
if([command isEqualToString:DATA]) {
// Received data from the server, usually sent to initialize
} else if([command isEqualToString:SETUP]) {
// Received the setup dict, usually tells us if the Arduino is connected
self.givenSetupDict = dictionary;
if([[dictionary objectForKey:@"ArduinoConnected"] intValue] == 0)
// Display a view that we are waiting for the Arduino to be connected
}
} else if([command isEqualToString:ACTION]) {
// Usually sent when there has been an action from the server side
} else if([command isEqualToString:TEXT]) {
// Usually useful data for our application's purpose
}
Legal
Arduino (http://arduino.cc)"Arduino" is a trademark of Arduino team.
Wijourno (http://robotgrrl.com/apps4arduino/wijourno.php)
Copyright © 2011, RobotGrrl.com. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of the RobotGrrl.com nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


