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

Top
Import and declare the service name (this should be the same on the server and client)
 
    #import "Wijourno_tags.h"
 
    #define SERVICE_NAME @"YourAppNameForArduino"
 
dealloc
Safely disconnect and release wijourno
 
    [wijourno closeSocket];
    [wijourno release];
 
applicationShouldTerminate:
Safely disconnect wijourno
 
    [wijourno closeSocket];
 
applicationDidFinishLaunching
Set 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];
 
connectPressed
This 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

Top
Import the tags
 
    #import "Wijourno_tags.h"
 
dealloc
Safely 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;
 
    }
 
applicationWillResignActive
Set a flag to let us know that the app is sleeping, and disconnect the client
 
    sleeping = YES;
    [wijourno disconnectClient];
 
applicationDidBecomeActive
If 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;
    }
 
applicationWillTerminate
Disconnect 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.


Page was last modified: January 31 2012 08:22:23.