<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Dr John Wordsworth</title>
	<atom:link href="http://www.johnwordsworth.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.johnwordsworth.com</link>
	<description>Mobile, iPhone and Game Programming Tutorials and Discussion</description>
	<lastBuildDate>Tue, 10 Apr 2012 17:06:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Adding charts to your iPhone / iPad App using Core Plot 0.9</title>
		<link>http://www.johnwordsworth.com/2011/10/adding-charts-to-your-iphone-ipad-app-using-core-plot/</link>
		<comments>http://www.johnwordsworth.com/2011/10/adding-charts-to-your-iphone-ipad-app-using-core-plot/#comments</comments>
		<pubDate>Fri, 21 Oct 2011 19:32:00 +0000</pubDate>
		<dc:creator>John Wordsworth</dc:creator>
				<category><![CDATA[iOS Development]]></category>
		<category><![CDATA[OSX Development]]></category>
		<category><![CDATA[Charts]]></category>
		<category><![CDATA[CorePlot]]></category>
		<category><![CDATA[Graphs]]></category>
		<category><![CDATA[iOS Charts]]></category>
		<category><![CDATA[iPhone Chart]]></category>

		<guid isPermaLink="false">http://www.johnwordsworth.com/?p=280</guid>
		<description><![CDATA[It&#8217;s unfortunate that Apple do not provide a charting library bundled with their frameworks, for I suspect that would save many developers the trouble of finding a charting library and deciphering the documentation. I&#8217;ve come to the conclusion that CorePlot is the best bet at the moment &#8211; it&#8217;s powerful and compatible with both iOS and ...]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s unfortunate that Apple do not provide a charting library bundled with their frameworks, for I suspect that would save many developers the trouble of finding a charting library and deciphering the documentation. I&#8217;ve come to the conclusion that <a title="CorePlot Charting Library for OSX, iPhone and iPad" href="http://code.google.com/p/core-plot/" target="_blank">CorePlot</a> is the best bet at the moment &#8211; it&#8217;s powerful and compatible with both iOS and OSX but unfortunately the documentation for isn&#8217;t great. So, we&#8217;re going to go through the process of adding a simple scatter chart to an iPad application.</p>
<p><span id="more-280"></span></p>
<p>Our goal is to build an application that contains a simple scatter graph with data stored in an NSArray (which could easily have been loaded from a CSV file). We aim to add this in a generic fashion, in a sub-view of a NIB file &#8211; so that you could drop this work into an app you&#8217;re working on without much work. We target the iPad, but the same method will work for the iPhone without any changes and will also work on OSX if you make a couple of minor changes.</p>
<p>This tutorial assumes that basic iOS programming knowledge and experience. Before we start, it&#8217;s worth noting that CorePlot is a very flexible library &#8211; it just takes a bit of getting used to. Unfortunately, the base documentation doesn&#8217;t help much when you&#8217;re getting started &#8211; so I&#8217;ll try to expose as much as I currently know about the library.</p>
<p><strong>1. Starting a new Project</strong></p>
<p>We&#8217;re going to develop a simple single-view iPad application &#8211; but you can add your CorePlot to any existing view in an application using the same method presented here. I use a class prefix of TUT to represent any classes I build during this tutorial.</p>
<div id="attachment_283" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.johnwordsworth.com/wp-content/uploads/2011/10/CorePlot-Tutorial-Step-1-Project-Settings.png"><img class="size-medium wp-image-283" title="CorePlot Tutorial - Step 1 - Project Settings" src="http://www.johnwordsworth.com/wp-content/uploads/2011/10/CorePlot-Tutorial-Step-1-Project-Settings-300x202.png" alt="CorePlot Tutorial - Step 1 - Project Settings" width="300" height="202" /></a><p class="wp-caption-text">Step 1. Project Settings</p></div>
<p><strong>2. Acquiring and Installing CorePlot</strong></p>
<p>When your project is ready and waiting, the first thing we will do is install the CorePlot library, which will expose the classes necessary for you to get started in adding your scatterplot to your application. Head over to <a title="CorePlot Charting Library for iPad, iPhone, OSX" href="http://code.google.com/p/core-plot/" target="_blank">the CorePlot website</a> and download the latest zip file. This tutorial is based on CorePlot 0.9, so if the code has changed significantly in the future &#8211; you might want to download version 0.9 to work through this tutorial and then figure out how the code has changed later.</p>
<p>When your download is complete, unzip the files in your Downloads directory. We&#8217;re going to install the static library, where the code has already been compiled as <strong>libCorePlot-CocoaTouch.a</strong>, but you could install the source-code version instead if you prefer &#8211; which would then recompile CorePlot when you build your app. Both methods are essentially the same, as you&#8217;ll still need to include the header files so that your code can access the methods. I keep my external libraries separate from my own source code, so we&#8217;re going to add a new folder at the root of our project called &#8216;Libs&#8217; and then create a sub-directory inside that called &#8216;CorePlot&#8217;. Now, from the zip file that you downloaded &#8211; you want to copy <strong>libCorePlot-CocoaTouch.a</strong> and the folder <strong>CorePlotHeaders</strong> from the folder <strong>CorePlot_0.9/Binaries/iOS/.</strong> Your directory structure should look like this;</p>
<div id="attachment_285" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.johnwordsworth.com/wp-content/uploads/2011/10/CorePlot-Tutorial-Step-2-Copying-the-Library-Files.png"><img class="size-medium wp-image-285" title="CorePlot Tutorial - Step 2 - Copying the Library Files" src="http://www.johnwordsworth.com/wp-content/uploads/2011/10/CorePlot-Tutorial-Step-2-Copying-the-Library-Files-300x195.png" alt="Step 2. Copying the Library Files" width="300" height="195" /></a><p class="wp-caption-text">Step 2. Copying the Library Files</p></div>
<p>Now that your files are in place, you just need to add them to your Xcode project. Drag and drop the whole Libs folder onto your Xcode file tree. Or, you can use the <strong>File -&gt; Add Files to &#8220;Core Plot Introduction&#8221;</strong> option from the files menu and select the Libs folder. There should now be  a Libs folder in your project sidebar containing the CorePlotHeaders and the libCorePlot file. Now, there are a couple of settings we need to tweak to get CorePlot working before we can start to implement our scatter plot. Select your project from the navigator panel in Xcode and then highlight the <strong>Build Settings</strong> tab. Filter the settings or locate &#8216;Other Linker Flags&#8217; from this list and then add <strong>-ObjC -all_load</strong> to these settings, as shown in the next figure;</p>
<div id="attachment_286" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.johnwordsworth.com/wp-content/uploads/2011/10/CorePlot-Tutorial-Step-2-Linker-Flags.png"><img class="size-medium wp-image-286" title="CorePlot Tutorial - Step 2 - Linker Flags" src="http://www.johnwordsworth.com/wp-content/uploads/2011/10/CorePlot-Tutorial-Step-2-Linker-Flags-300x136.png" alt="Step 2. Setting Other Linker Flags" width="300" height="136" /></a><p class="wp-caption-text">Step 2. Setting Other Linker Flags</p></div>
<p>There&#8217;s just one more step before we can start working with CorePlot in our application. As CorePlot makes use of Apple&#8217;s Core Animation code, which is a part of the QuartzCore framework &#8211; we need to ensure that our project is linking against the QuartzCore code. With the project still selected in Xcode, highlight the <strong>Build Phases</strong> tab. Expand the <strong>Link Binary with Libraries</strong> panel and click on the plus button at the bottom. Now select <strong>QuartzCore.framework</strong> from the list and hit ok. I usually copy the reference in my project into the Framework folder to be tidy &#8211; but this isn&#8217;t a necessity.</p>
<div id="attachment_287" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.johnwordsworth.com/wp-content/uploads/2011/10/CorePlot-Tutorial-Step-2-Linking-with-QuartzCore.png"><img class="size-medium wp-image-287" title="CorePlot Tutorial - Step 2 - Linking with QuartzCore" src="http://www.johnwordsworth.com/wp-content/uploads/2011/10/CorePlot-Tutorial-Step-2-Linking-with-QuartzCore-300x157.png" alt="Step 2. Linking with QuartzCore" width="300" height="157" /></a><p class="wp-caption-text">Step 2. Linking with QuartzCore</p></div>
<p><strong>3. Adding a Graph Hosting View to our Interface</strong></p>
<p>In order to add a CorePlot chart space to our application, we start by setting up a &#8216;Hosting View&#8217; which we will later attach our graph(s) too. We&#8217;re just creating a placeholder in our NIB at the moment, into which we will tell CorePlot to start drawing using our code later on.</p>
<p>We start by adding a label to the top of the interface with some dummy text and change the background colour of the main XIB view to <strong>Scroll View Textured Background Color</strong> to make it looks swish. Next, drag and drop a <strong>UIView</strong> component from the object library onto your project. You would normally make this as big as possible, as we would adding padding within CorePlot (to leave spill over space for axis labels). However, for this tutorial &#8211; I&#8217;ve left a border to make it easier to see what&#8217;s going on in the figures. Next, select the view you&#8217;ve just added and change it&#8217;s class in the property panel to the right. It&#8217;s class should be; <strong>CPTGraphHostingView.</strong> You should now have something that looks like the next figure (notice the object hierarchy on the left and the UIView&#8217;s class at the top right).</p>
<div id="attachment_288" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.johnwordsworth.com/wp-content/uploads/2011/10/CorePlot-Tutorial-Step-3-Adding-a-Hosting-View.png"><img class="size-medium wp-image-288" title="CorePlot Tutorial - Step 3 - Adding a Hosting View" src="http://www.johnwordsworth.com/wp-content/uploads/2011/10/CorePlot-Tutorial-Step-3-Adding-a-Hosting-View-300x232.png" alt="Step 3. Adding a Hosting View" width="300" height="232" /></a><p class="wp-caption-text">Step 3. Adding a Hosting View</p></div>
<p><strong>4. Creating our Scatter Plot object</strong></p>
<p>CorePlot acquires data for its plots much like UITableView does &#8211; by calling specific methods on the class you have set as the Graph&#8217;s delegate. Incidentally, it also delegates many of it&#8217;s features this way too, for instance if you want the user to be able to interact with the chart. So, much like a table view, you could set the main ViewController as your delegate and not add an extra class to your code. However, in order to keep your charts re-usable and interchangeable, I think it&#8217;s best to create a new class that will do all the work for your chart.</p>
<p>So, we add a new class to our project <strong>TUTSimpleScatterPlot</strong>, which is simply a subclass of <strong>NSObject</strong>. In <strong>TUTSimpleScatterPlot.h</strong> we need to import the CorePlot libraries; <strong>#import &#8220;CorePlot-CocoaTouch.h&#8221; </strong>and then we define a few properties for the objects we need to keep a reference too. The header file for our chart object looks like this&#8230;</p>
<p><strong>TUTSimpleScatterPlot.h</strong></p>
<pre class="brush: plain; title: ; notranslate">
#import
#import &quot;CorePlot-CocoaTouch.h&quot;

@interface TUTSimpleScatterPlot : NSObject  {
	CPTGraphHostingView *_hostingView;
	CPTXYGraph *_graph;
	NSMutableArray *_graphData;
}

@property (nonatomic, retain) CPTGraphHostingView *hostingView;
@property (nonatomic, retain) CPTXYGraph *graph;
@property (nonatomic, retain) NSMutableArray *graphData;

// Method to create this object and attach it to it's hosting view.
-(id)initWithHostingView:(CPTGraphHostingView *)hostingView andData:(NSMutableArray *)data;

// Specific code that creates the scatter plot.
-(void)initialisePlot;

@end
</pre>
<p>We need to keep hold of 3 objects to make our chart work. We will pass the hosting view from our XIB file and an array of data when we call <strong>initWithHostingView:andData:</strong> while creating an instance of our chart. We create the <strong>CPTXYGraph</strong> and setup our chart when <strong>initialisePlot</strong> is called &#8211; which we will usually call shortly after we initialise our object. Notice we have stated that our object responds to the <strong>CPTScatterPlotDataSource</strong> delegate methods in the class definition.</p>
<p>Next, we&#8217;re going to write the init and initialisePlot methods, as well as the methods from the CPTScatterPlotDataSource protocol required to get our chart working. In time honoured tradition, I&#8217;ll throw the code at you first, and then explain it. While it looks like a lot of code, most of it involves configuring certain graph elements &#8211; it&#8217;s simpler than it first appears.</p>
<p><strong>TUTSimpleScatterPlot.m</strong></p>
<pre class="brush: plain; title: ; notranslate">
#import &quot;TUTSimpleScatterPlot.h&quot;

@implementation TUTSimpleScatterPlot
@synthesize hostingView = _hostingView;
@synthesize graph = _graph;
@synthesize graphData = _graphData;

// Initialise the scatter plot in the provided hosting view with the provided data.
// The data array should contain NSValue objects each representing a CGPoint.
-(id)initWithHostingView:(CPTGraphHostingView *)hostingView andData:(NSMutableArray *)data
{
	self = [super init];

	if ( self != nil ) {
		self.hostingView = hostingView;
		self.graphData = data;
		self.graph = nil;
	}

	return self;
}

// This does the actual work of creating the plot if we don't already have a graph object.
-(void)initialisePlot
{
	// Start with some simple sanity checks before we kick off
	if ( (self.hostingView == nil) || (self.graphData == nil) ) {
		NSLog(@&quot;TUTSimpleScatterPlot: Cannot initialise plot without hosting view or data.&quot;);
		return;
	}

	if ( self.graph != nil ) {
		NSLog(@&quot;TUTSimpleScatterPlot: Graph object already exists.&quot;);
		return;
	}

	// Create a graph object which we will use to host just one scatter plot.
	CGRect frame = [self.hostingView bounds];
	self.graph = [[[CPTXYGraph alloc] initWithFrame:frame] autorelease];

	// Add some padding to the graph, with more at the bottom for axis labels.
	self.graph.plotAreaFrame.paddingTop = 20.0f;
	self.graph.plotAreaFrame.paddingRight = 20.0f;
	self.graph.plotAreaFrame.paddingBottom = 50.0f;
	self.graph.plotAreaFrame.paddingLeft = 20.0f;

	// Tie the graph we've created with the hosting view.
	self.hostingView.hostedGraph = self.graph;

	// If you want to use one of the default themes - apply that here.
	//[self.graph applyTheme:[CPTTheme themeNamed:kCPTDarkGradientTheme]];

	// Create a line style that we will apply to the axis and data line.
	CPTMutableLineStyle *lineStyle = [CPTMutableLineStyle lineStyle];
	lineStyle.lineColor = [CPTColor whiteColor];
	lineStyle.lineWidth = 2.0f;

	// Create a text style that we will use for the axis labels.
	CPTMutableTextStyle *textStyle = [CPTMutableTextStyle textStyle];
	textStyle.fontName = @&quot;Helvetica&quot;;
	textStyle.fontSize = 14;
	textStyle.color = [CPTColor whiteColor];

	// Create the plot symbol we're going to use.
	CPTPlotSymbol *plotSymbol = [CPTPlotSymbol crossPlotSymbol];
	plotSymbol.lineStyle = lineStyle;
	plotSymbol.size = CGSizeMake(8.0, 8.0);

	// Setup some floats that represent the min/max values on our axis.
	float xAxisMin = -10;
	float xAxisMax = 10;
	float yAxisMin = 0;
	float yAxisMax = 100;

	// We modify the graph's plot space to setup the axis' min / max values.
	CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)self.graph.defaultPlotSpace;
	plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(xAxisMin) length:CPTDecimalFromFloat(xAxisMax - xAxisMin)];
	plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(yAxisMin) length:CPTDecimalFromFloat(yAxisMax - yAxisMin)];

	// Modify the graph's axis with a label, line style, etc.
	CPTXYAxisSet *axisSet = (CPTXYAxisSet *)self.graph.axisSet;

	axisSet.xAxis.title = @&quot;Data X&quot;;
	axisSet.xAxis.titleTextStyle = textStyle;
	axisSet.xAxis.titleOffset = 30.0f;
	axisSet.xAxis.axisLineStyle = lineStyle;
	axisSet.xAxis.majorTickLineStyle = lineStyle;
	axisSet.xAxis.minorTickLineStyle = lineStyle;
	axisSet.xAxis.labelTextStyle = textStyle;
	axisSet.xAxis.labelOffset = 3.0f;
	axisSet.xAxis.majorIntervalLength = CPTDecimalFromFloat(2.0f);
	axisSet.xAxis.minorTicksPerInterval = 1;
	axisSet.xAxis.minorTickLength = 5.0f;
	axisSet.xAxis.majorTickLength = 7.0f;

	axisSet.yAxis.title = @&quot;Data Y&quot;;
	axisSet.yAxis.titleTextStyle = textStyle;
	axisSet.yAxis.titleOffset = 40.0f;
	axisSet.yAxis.axisLineStyle = lineStyle;
	axisSet.yAxis.majorTickLineStyle = lineStyle;
	axisSet.yAxis.minorTickLineStyle = lineStyle;
	axisSet.yAxis.labelTextStyle = textStyle;
	axisSet.yAxis.labelOffset = 3.0f;
	axisSet.yAxis.majorIntervalLength = CPTDecimalFromFloat(10.0f);
	axisSet.yAxis.minorTicksPerInterval = 1;
	axisSet.yAxis.minorTickLength = 5.0f;
	axisSet.yAxis.majorTickLength = 7.0f;

	// Add a plot to our graph and axis. We give it an identifier so that we
	// could add multiple plots (data lines) to the same graph if necessary.
	CPTScatterPlot *plot = [[[CPTScatterPlot alloc] init] autorelease];
	plot.dataSource = self;
	plot.identifier = @&quot;mainplot&quot;;
	plot.dataLineStyle = lineStyle;
	plot.plotSymbol = plotSymbol;
	[self.graph addPlot:plot];
}

// Delegate method that returns the number of points on the plot
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
	if ( [plot.identifier isEqual:@&quot;mainplot&quot;] )
	{
		return [self.graphData count];
	}

	return 0;
}

// Delegate method that returns a single X or Y value for a given plot.
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
	if ( [plot.identifier isEqual:@&quot;mainplot&quot;] )
	{
		NSValue *value = [self.graphData objectAtIndex:index];
		CGPoint point = [value CGPointValue];

		// FieldEnum determines if we return an X or Y value.
		if ( fieldEnum == CPTScatterPlotFieldX )
		{
			return [NSNumber numberWithFloat:point.x];
		}
		else	// Y-Axis
		{
			return [NSNumber numberWithFloat:point.y];
		}
	}

	return [NSNumber numberWithFloat:0];
}

@end
</pre>
<p>First of all, lets look at each of the methods above and describe what they do, and then we&#8217;ll look at some of the Core Plot objects that we make use of in the initialisePlot method.</p>
<p>So, <strong>initWithHostingView:andData</strong> simple initialises this object and retains a reference to the hosting view and data array which is fed to this method. <strong>initialisePlot</strong> is designed to be called shortly after the init method, but has been separated so that you can choose when the brunt of the work is done in creating the graph. This method provides the bulk of this class, which mostly consists of setting up the graph object with the required axis settings, line styles and label styles etc.</p>
<p><strong>numberOfReportsForPlot:</strong> is a delegate method which simply returns the number of unique data points that exist for a given plot. If you are using this object as a delegate for multiple plots, you can determine which plot you should return data for by interrogating the identifier property &#8211; which you set earlier in the initialisePlot method. Finally, <strong>numberForPlot:field:recordIndex:</strong> will be called twice per data point in each plot. <strong>fieldEnum</strong> tells you whether the graph object is expecting the X or Y value for a given data point at <strong>index</strong>. Like with numberOfReportsForPlot, you can differentiate between multiple plots by first checking the identifier of the plot.</p>
<p>The intialisePlot method is fairly self-explanatory when reading it with the comments. However, it took me a while to get my head around the different objects made available by CorePlot. The <strong>CPTXYGraph</strong> represents an area into which a 2-dimensional graph will be drawn inside of a HostingView which exists in the parent UIView. The graph comes with it&#8217;s own <strong>plotAreaFrame</strong> (the area inside the graph that the actual data will be rendered), a <strong>plotSpace</strong> (the minimum and maximum values of X and Y that will be drawn on your chart) and an <strong>axisSet </strong>(essentially style and rendering options for the axis on this graph). You generally pull out a reference from the graph object for each of these and then manipulate them to design your chart.</p>
<p>The most prominent style and design objects you will use are; <strong>CPTMutableLineStyle </strong>- which represents a set of options for how a given line should be drawn (width / colour), <strong>CPTMutableTextStyle</strong> - a set of objects describing how a text label should be drawn (font, size, colour) and <strong>CPTPlotSymbol</strong> - representing an ellipse or cross for instance that will appear at the actual data points on your chart lines. When all of your chart framework is setup, you can then add one or more <strong>CPTScatterPlot</strong> objects to your graph &#8211; each one representing a unique data set or line on your chart. We only add one in this example and set the delegate to <strong>self</strong> (as we&#8217;ve set the delegate methods which return the data), a line style and a plot symbol. We also set an identifier incase we add more plots in the future so that the delegates can tell which plot the graph is expecting data for when calling a delegate method.</p>
<p><strong>5. Hooking it all together</strong></p>
<p>Last but not least, we need to bring all of these elements together and look at our creation. So, we need to create an IBOutlet for our Graph Hosting View in TUTViewController. Your TUTViewController.h should look like the following;</p>
<p><strong>TUTViewController.h</strong></p>
<pre class="brush: plain; title: ; notranslate">
#import
#import &quot;CorePlot-CocoaTouch.h&quot;
#import &quot;TUTSimpleScatterPlot.h&quot;

@interface TUTViewController : UIViewController {
	IBOutlet CPTGraphHostingView *_graphHostingView;
	TUTSimpleScatterPlot *_scatterPlot;
}

@property (nonatomic, retain) TUTSimpleScatterPlot *scatterPlot;

@end
</pre>
<p>Now, don&#8217;t forget to hook your CPTGraphHostingView from the TUTViewController back to the view that you added to the NIB right back at the start of this tutorial. Load up TUTViewController.xib and Ctrl-Click-Drag from &#8216;Files Owner&#8217; to the Hosting View and then select graphHostingView as the outlet. We&#8217;ll create some sample data and then create the scatterPlot object in the viewWillAppear method of the View Controller;</p>
<p><strong>TUTViewController.m</strong></p>
<pre class="brush: plain; title: ; notranslate">
- (void)viewWillAppear:(BOOL)animated
{
	[super viewWillAppear:animated];

	NSMutableArray *data = [NSMutableArray array];
	[data addObject:[NSValue valueWithCGPoint:CGPointMake(-10, 100)]];
	[data addObject:[NSValue valueWithCGPoint:CGPointMake(-8, 50)]];
	[data addObject:[NSValue valueWithCGPoint:CGPointMake(-6, 20)]];
	[data addObject:[NSValue valueWithCGPoint:CGPointMake(-4, 10)]];
	[data addObject:[NSValue valueWithCGPoint:CGPointMake(-2, 5)]];
	[data addObject:[NSValue valueWithCGPoint:CGPointMake(0, 0)]];
	[data addObject:[NSValue valueWithCGPoint:CGPointMake(2, 4)]];
	[data addObject:[NSValue valueWithCGPoint:CGPointMake(4, 16)]];
	[data addObject:[NSValue valueWithCGPoint:CGPointMake(6, 36)]];
	[data addObject:[NSValue valueWithCGPoint:CGPointMake(8, 64)]];
	[data addObject:[NSValue valueWithCGPoint:CGPointMake(10, 100)]];

	self.scatterPlot = [[TUTSimpleScatterPlot alloc] initWithHostingView:_graphHostingView andData:data];
	[self.scatterPlot initialisePlot];
}
</pre>
<p>Note that we&#8217;re storing our data as a simple array of CGPoints. However, as CGPoints aren&#8217;t descended from NSObject, we can&#8217;t store them in an NSArray directly, so we wrap them up in an NSValue object within the array.</p>
<p>Anyway, phew, it feels like a lot of work &#8211; but we&#8217;re finally there. The golden spot of any tutorial &#8211; the screenshot of the final product!</p>
<div id="attachment_298" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.johnwordsworth.com/wp-content/uploads/2011/10/CorePlot-Tutorial-End-Result.png"><img class="size-medium wp-image-298" title="CorePlot Tutorial - End Result" src="http://www.johnwordsworth.com/wp-content/uploads/2011/10/CorePlot-Tutorial-End-Result-300x232.png" alt="CorePlot Tutorial - End Result" width="300" height="232" /></a><p class="wp-caption-text">The End Result</p></div>
<p>If you&#8217;re having any problems getting this to work in your own app, then please don&#8217;t hesitate to get in touch by leaving a comment below &#8211; I&#8217;ll do my best to reply in a timely manner. If you want to download the code from the sample project, you can do so using the link below.</p>
<p><a href="http://www.johnwordsworth.com/wp-content/uploads/2011/10/core-plot-intro-v01.zip">Download the Core Plot Introduction Xcode Project</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnwordsworth.com/2011/10/adding-charts-to-your-iphone-ipad-app-using-core-plot/feed/</wfw:commentRss>
		<slash:comments>63</slash:comments>
		</item>
		<item>
		<title>Wrapping Box2D Debug into a Cocos2D Layer</title>
		<link>http://www.johnwordsworth.com/2011/09/wrapping-box2d-debug-into-a-cocos2d-layer/</link>
		<comments>http://www.johnwordsworth.com/2011/09/wrapping-box2d-debug-into-a-cocos2d-layer/#comments</comments>
		<pubDate>Fri, 23 Sep 2011 00:50:03 +0000</pubDate>
		<dc:creator>John Wordsworth</dc:creator>
				<category><![CDATA[iOS Development]]></category>
		<category><![CDATA[box2d]]></category>
		<category><![CDATA[cocos2d]]></category>
		<category><![CDATA[cocos2d-iphone]]></category>
		<category><![CDATA[iOS]]></category>

		<guid isPermaLink="false">http://www.johnwordsworth.com/?p=221</guid>
		<description><![CDATA[When I first started integrating Box2D into my Cocos2D project, I found the whole process a little jarring. While I&#8217;d used C++ before, this was the first time I&#8217;d seen it mixed with Objective-C. This code snippet simply wraps the standard Box2D Debug calls from GLES-Render.h (included with Cocos2D) in it&#8217;s own CCLayer, so that ...]]></description>
			<content:encoded><![CDATA[<p>When I first started integrating Box2D into my Cocos2D project, I found the whole process a little jarring. While I&#8217;d used C++ before, this was the first time I&#8217;d seen it mixed with Objective-C. This code snippet simply wraps the standard Box2D Debug calls from GLES-Render.h (included with Cocos2D) in it&#8217;s own CCLayer, so that you can implement it quickly and easily. It also allows you to turn the layer on an off easily as you would any other CCLayer.</p>
<p><span id="more-221"></span></p>
<p>Please note, that this is not an introduction to using Box2D with Cocos2D. This is intended as a drop-in class that you can use to simplify the process of displaying debug information from Box2D. For more information about using Box2D &#8211; see <a href="http://www.raywenderlich.com/457/intro-to-box2d-with-cocos2d-tutorial-bouncing-balls">Ray Wenderlich&#8217;s great post on the subject</a>.</p>
<p><strong>Note:</strong> This class has now been included in <a title="Kobold2D - A beginner friendly version of Cocos2D" href="http://www.kobold2d.com/" target="_blank">Kobold2D</a> (<a title="Kobold2D 1.0.1 Release Notes" href="http://www.learn-cocos2d.com/2011/12/kobold2d-v101/" target="_blank">since v1.0.1</a>). Kobold2D is a beginner friendly version of Cocos2D which includes a number of additional, commonly used libraries already integrated with it. If you just want to use this class out of the box without any setup and/or if you&#8217;re just starting out with Cocos2D, it&#8217;s definitely worth checking out Kobold2D.</p>
<p>In order to implement this class, you will need to be ensure that the relevant Box2D files are included in your project, as well as the default GLES-Render.h that comes packaged with the Cocos2D Box2D project template. GLES-Render.h provides all of the low-level calls required by Box2D to draw the objects within a Box2D world to the screen.</p>
<p>So, to create our CCLayer which draws the Box2D debug information, we create the class BoxDebugLayer, which inherits from CCLayer. This layer needs to maintain an instance of the GLESDebugDraw class (from GLES-Render &#8211; used to do the actual rendering). We also keep hold of a pointer to the world and the PTM ratio for good measure.</p>
<p><strong>BoxDebugLayer.h</strong> (<a href="http://www.johnwordsworth.com/wp-content/uploads/2011/09/BoxDebugLayer.h">Download</a>)</p>
<pre class="brush: plain; title: ; notranslate">
#import &quot;cocos2d.h&quot;
#import &quot;Box2D.h&quot;
#import &quot;GLES-Render.h&quot;

@interface BoxDebugLayer : CCLayer {
	GLESDebugDraw* _debugDraw;	// The DebugDraw instance from GLES-Render
	b2World *_boxWorld;		// The Box2D world this is attached to
	int _ptmRatio;			// The PTM Ratio used in this world
}

/** Return an autoreleased debug layer */
+(BoxDebugLayer *)debugLayerWithWorld:(b2World *)world ptmRatio:(int)ptmRatio;
+(BoxDebugLayer *)debugLayerWithWorld:(b2World *)world ptmRatio:(int)ptmRatio flags:(uint32)flags;

/** Initialise a debug layer with the given parameters. */
-(id)initWithWorld:(b2World *)world ptmRatio:(int)ptmRatio;
-(id)initWithWorld:(b2World *)world ptmRatio:(int)ptmRatio flags:(uint32)flags;

@end
</pre>
<p><strong>BoxDebugLayer.mm</strong> (<a href="http://www.johnwordsworth.com/wp-content/uploads/2011/09/BoxDebugLayer.mm">Download</a>)</p>
<pre class="brush: plain; title: ; notranslate">
#import &quot;BoxDebugLayer.h&quot;

@implementation BoxDebugLayer

/** Create a debug layer with the given world and ptm ratio */
+(BoxDebugLayer *)debugLayerWithWorld:(b2World *)world ptmRatio:(int)ptmRatio
{
    return [[[BoxDebugLayer alloc] initWithWorld:world ptmRatio:ptmRatio] autorelease];
}

/** Create a debug layer with the given world, ptm ratio and debug display flags */
+(BoxDebugLayer *)debugLayerWithWorld:(b2World *)world ptmRatio:(int)ptmRatio flags:(uint32)flags
{
    return [[[BoxDebugLayer alloc] initWithWorld:world ptmRatio:ptmRatio flags:flags] autorelease];
}

/** Create a debug layer with the given world and ptm ratio */
-(id)initWithWorld:(b2World*)world ptmRatio:(int)ptmRatio
{
    return [self initWithWorld:world ptmRatio:ptmRatio flags:b2DebugDraw::e_shapeBit];
}

/** Create a debug layer with the given world, ptm ratio and debug display flags */
-(id)initWithWorld:(b2World*)world ptmRatio:(int)ptmRatio flags:(uint32)flags
{
	if ((self = [self init])) {
		_boxWorld = world;
        _ptmRatio = ptmRatio;
		_debugDraw = new GLESDebugDraw( ptmRatio );

		_boxWorld-&gt;SetDebugDraw(_debugDraw);
		_debugDraw-&gt;SetFlags(flags);
	}

	return self;
}

/** Clean up by deleting the debug draw layer. */
-(void)dealloc
{
	_boxWorld = NULL;

	if ( _debugDraw != NULL ) {
		delete _debugDraw;
	}

	[super dealloc];
}

/** Tweak a few OpenGL options and then draw the Debug Layer */
-(void)draw
{
	glDisable(GL_TEXTURE_2D);
	glDisableClientState(GL_COLOR_ARRAY);
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);

	glPushMatrix();
	glScalef( CC_CONTENT_SCALE_FACTOR(), CC_CONTENT_SCALE_FACTOR(), 1.0f);
	_boxWorld-&gt;DrawDebugData();
	glPopMatrix();

	glEnable(GL_TEXTURE_2D);
	glEnableClientState(GL_COLOR_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}

@end
</pre>
<h3>Using this class</h3>
<p>Using this class in your code is as simple as just adding this layer as a child to your game layer. You need to inform the BoxDebugLayer class of which box2DWorld you would like it to attach to, and what your PTM ratio is for this world. Optionally, you can also provide the flags for which debug information you would like in the init method.</p>
<p>Adding this layer to your project is as simple as&#8230;</p>
<pre class="brush: plain; title: ; notranslate">
[self addChild:[BoxDebugLayer debugLayerWithWorld:_boxWorld ptmRatio:GAME_PTM_RATIO] z:10000];
</pre>
<p>If you would like to enable specific flags, use the alternative constructor&#8230;</p>
<pre class="brush: plain; title: ; notranslate">
uint32 flags = b2DebugDraw::e_aabbBit | b2DebugDraw::e_centerOfMassBit | b2DebugDraw::e_jointBit | b2DebugDraw::e_pairBit | b2DebugDraw::e_shapeBit;
[self addChild:[BoxDebugLayer debugLayerWithWorld:_boxWorld ptmRatio:GAME_PTM_RATIO flags:flags] z:10000];
</pre>
<h3>Limitations</h3>
<p>There are some limitations of this code as it stands. As each DebugLayer has to register itself with the box2D world, adding two debug layers to the same world will not work as expected. The second world will likely override the first debug layer, making the first defunct.</p>
<p>I also haven&#8217;t added any code to allow customisation of how the debug layer is drawn. In my own code, I simply change the GLES-Render.m file if I ever need to tweak how the debug information is drawn. This usually only includes changing a line width, so that the debug-lines are clearly visible over my artwork. However, if you have the time and inclination &#8211; I suspect you could add these options to this class, making it easier to customise debug information within the Box2D Debug Layer.</p>
<h3>Explanation</h3>
<p>If you are interested in how this layer works, then I&#8217;ll talk through the main methods below.</p>
<p><strong>initWithWorld:ptmRatio:flags:</strong> is the main initialisation method that will ultimately be called to create this object (calling the shorter init method calls this one with default options).</p>
<p>This method maintains a local copy of the box2D world we&#8217;re working with and the PTM ratio. We then create an instance of the GLESDebugDraw class provided to us in GLES-Render.h (packaged with Cocos2D). GLESDebugDraw implements a number of methods that Box2D expects to use when drawing debug information to the screen. This class handles the code that does the actual drawing of the debug information even though the Box2D library will be driving that code to draw the information.</p>
<p>There are a number of flags you can provide to inform GLESDebugDraw what you would like to see drawn. The following options exist;</p>
<ul>
<li>b2DebugDraw::e_aabbBit &#8211; Draw the axis aligned bounding boxes.</li>
<li>b2DebugDraw::e_centerOfMassBit &#8211; Draw the centre of Mass for bodies.</li>
<li>b2DebugDraw::e_jointBit &#8211; Draw any joints between fixtures.</li>
<li>b2DebugDraw::e_pairBit &#8211; Draw broad-phase pairs.</li>
<li>b2DebugDraw::e_shapeBit &#8211; Draw outline shapes for fixtures / bodies.</li>
</ul>
<p>Naturally, in our <strong>dealloc</strong> method we clean up after ourselves. As the Box2D and GLESDebugDraw classes aren&#8217;t NSObjects / objective-C, we don&#8217;t use the normal retain / release mechanics. Instead we delete them the old fashioned C++ way.</p>
<p>The <strong>draw</strong> method prepares OpenGL for the debug draw operation. Whereas with Cocos2D we&#8217;ve been drawing textured sprites, the debug information wants to make use of the primitive drawing methods. As such, before we call GLESDebugDraw we have to disable all of the textured drawing features of OpenGL so that it only expects to receive primitive information.</p>
<p>We then scale the world to account for the retina display (if required) before asking Box2D to draw the information. This is based on the assumption that you will be using one world size for your iPhone app regardless of whether it&#8217;s retina or not &#8211; so we need to scale the points to pixels in OpenGL. Last but not least, we return OpenGL the state it was in before we did our work.</p>
<p>That&#8217;s it. If you find this useful, add anything to your own implementation or think this class needs any additional features &#8211; please leave a comment below.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnwordsworth.com/2011/09/wrapping-box2d-debug-into-a-cocos2d-layer/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>iOS &#8211; performSelectorOnMainThread with Multiple Objects</title>
		<link>http://www.johnwordsworth.com/2011/08/ios-performselectoronmainthread-with-multiple-objects/</link>
		<comments>http://www.johnwordsworth.com/2011/08/ios-performselectoronmainthread-with-multiple-objects/#comments</comments>
		<pubDate>Mon, 22 Aug 2011 15:32:05 +0000</pubDate>
		<dc:creator>John Wordsworth</dc:creator>
				<category><![CDATA[iOS Development]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[NSInvocation]]></category>
		<category><![CDATA[performSelectorOnMainThread]]></category>

		<guid isPermaLink="false">http://www.johnwordsworth.com/?p=205</guid>
		<description><![CDATA[I recently ran into the situation where I wanted to call NSObject&#8217;s performSelectorOnMainThread with multiple arguments. While it wasn&#8217;t massively difficult, it was a bit more fiddly than I first expected &#8211; you have to get your hands dirty with NSInvocation. I&#8217;ve built a category that adds an additional method to NSObject which will allow ...]]></description>
			<content:encoded><![CDATA[<p>I recently ran into the situation where I wanted to call NSObject&#8217;s <em><strong>performSelectorOnMainThread</strong></em> with multiple arguments. While it wasn&#8217;t massively difficult, it was a bit more fiddly than I first expected &#8211; you have to get your hands dirty with <em>NSInvocation</em>. I&#8217;ve built a category that adds an additional method to NSObject which will allow you to call a performSelectorOnMainThread method with any number of objects as parameters. Feel free to use it in your own projects!<br />
<span id="more-205"></span></p>
<p>If you&#8217;re new to Objective-C, categories allows you to add additional methods to existing classes &#8211; without having to have access to the source code for that class. In this instance, we will add a new method to NSObject (and therefore, every object that inherits from NSObject) that will act much like the already existing performSelectorOnMainThread method, only it will accept any number of objects as input. You can read more about categories in <a title="Learn Objective-C Guide" href="http://cocoadevcentral.com/d/learn_objectivec/">this very helpful Objective-C guide</a>.</p>
<p>Our code consists of two parts, the header file &#8211; which will define the extra method for NSObject, and the .m file, as per usual. The header file is simple (excuse my long file name, I like to be precise);</p>
<p><strong>NSObject+PerformSelectorOnMainThreadMultipleArgs.h</strong></p>
<pre class="brush: plain; title: ; notranslate">
#import &lt;Foundation/Foundation.h&gt;

@interface NSObject (PerformSelectorOnMainThreadMultipleArgs)

-(void)performSelectorOnMainThread:(SEL)selector waitUntilDone:(BOOL)wait withObjects:(NSObject *)object, ... NS_REQUIRES_NIL_TERMINATION;

@end
</pre>
<p>Nothing really out of the ordinary here. Just notice that using the (parathesis) after NSObject tells Objective-C that we&#8217;re making a category on NSObject. It&#8217;s also worth noting that the &#8216;with objects&#8217; parameter for the method we&#8217;ve created has a comma and 3 ellipsis after the first parameter&#8217;s variable name. This is stating that we&#8217;re expecting a list of parameters. The NS_REQUIRES_NIL_TERMINATION states that, much like some of the NSMutableArray instance methods, we&#8217;re expecting a list which is terminated by a nil value. Now, onto the code for this method;</p>
<p><strong>NSObject+PerformSelectorOnMainThreadMultipleArgs.m</strong></p>
<pre class="brush: plain; title: ; notranslate">
#import &quot;NSObject+PerformSelectorOnMainThreadMultipleArgs.h&quot;

@implementation NSObject (PerformSelectorOnMainThreadMultipleArgs)

-(void)performSelectorOnMainThread:(SEL)selector waitUntilDone:(BOOL)wait withObjects:(NSObject *)firstObject, ...
{
    // First attempt to create the method signature with the provided selector.
    NSMethodSignature *signature = [self methodSignatureForSelector:selector];

    if ( !signature ) {
        NSLog(@&quot;NSObject: Method signature could not be created.&quot;);
        return;
    }

    // Next we create the invocation that will actually call the required selector.
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
    [invocation setTarget:self];
    [invocation setSelector:selector];

    // Now add arguments from the variable list of objects (nil terminated).
    va_list args;
    va_start(args, firstObject);
    int nextArgIndex = 2;

    for (NSObject *object = firstObject; object != nil; object = va_arg(args, NSObject*))
    {
        if ( object != [NSNull null] )
        {
            [invocation setArgument:&amp;object atIndex:nextArgIndex];
        } 

        nextArgIndex++;
    }	

    va_end(args);

    [invocation retainArguments];
    [invocation performSelectorOnMainThread:@selector(invoke) withObject:nil waitUntilDone:wait];
}

@end
</pre>
<p>Now, you probably came here just looking for some code &#8211; so I won&#8217;t put too much tutorial in here. First off, let me just say that I&#8217;ve switched around the parameters for the method from the standard order so that the variable length list is the last parameter. Next up, I&#8217;ll just touch on the two main elements of the code.</p>
<p>First of all, this code relies on NSInvocation to do the leg work. NSInvocation represents the action of calling a method, but wraps it up in an object &#8211; so that you can do a number of things with it. In this case, it means that we can build the NSInvocation from the list of input objects that we&#8217;ve received, and then ensure that the NSInvocation object calls it&#8217;s own invoke method (calling the selector on the calling item) on the main thread. This means that we can lever the regular performSelectorOnMainThread functionality without having to do too much work on our own.</p>
<p>Secondly, the va_list is what allows us to pass the method a variable number of arguments. We keep popping objects off the argument list (in the for loop) until we reach a nil object. However, as we might also want to pass nil as an argument to our selector, I&#8217;ve made it such that you can pass NSNull which will then be interpreted as a nil argument in the final selector call. Here we simply pop the arguments from the withObjects parameter to the method and add them as arguments to the invocation. Note that we start at argument 2 for the invocation as NSInvocation&#8217;s arguments 0 and 1 are used for other purposes. So argument 2 actually corresponds to the first argument for the selector you&#8217;ve chosen.</p>
<p>That&#8217;s about it really &#8211; if you have any questions, please feel free to ask away in the comments section below. Otherwise, enjoy the code!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnwordsworth.com/2011/08/ios-performselectoronmainthread-with-multiple-objects/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Loading Cocos2D Sprite Frame Animations from Plist Files</title>
		<link>http://www.johnwordsworth.com/2011/07/loading-cocos2d-sprite-frame-animations-from-plist-files/</link>
		<comments>http://www.johnwordsworth.com/2011/07/loading-cocos2d-sprite-frame-animations-from-plist-files/#comments</comments>
		<pubDate>Mon, 11 Jul 2011 18:54:58 +0000</pubDate>
		<dc:creator>John Wordsworth</dc:creator>
				<category><![CDATA[iOS Development]]></category>
		<category><![CDATA[CCAnimation]]></category>
		<category><![CDATA[CCAnimationFrameCache]]></category>
		<category><![CDATA[cocos2d]]></category>
		<category><![CDATA[Knight Terrors]]></category>

		<guid isPermaLink="false">http://www.johnwordsworth.com/?p=175</guid>
		<description><![CDATA[In a game that a friend and I are working on (Knight Terrors) we wanted a system to pre-load animations into CCAnimationFrameCache without having to hardcode any of that configuration. This means that our designer and artist, Jackson Matthews, can add and remove frames from a creature&#8217;s animation without having to come back to me with ...]]></description>
			<content:encoded><![CDATA[<p>In a game that a friend and I are working on (Knight Terrors) we wanted a system to pre-load animations into CCAnimationFrameCache without having to hardcode any of that configuration. This means that our designer and artist, <a href="http://www.jacksonmatthews.co.uk">Jackson Matthews</a>, can add and remove frames from a creature&#8217;s animation without having to come back to me with a frame list to paste back into the code. I will assume you have knowledge of <a title="Introduction to CCSpriteFrameCache" href="http://www.cocos2d-iphone.org/archives/633" target="_blank">CCSpriteFrameCache</a> and CCAnimations within cocos2d before embarking on this. If not, you can read up on them through the provided links.</p>
<p><span id="more-175"></span></p>
<div style="color: darkred">
<b>Important Note. This feature has been part of cocos2d since v1.1 and may have changed since. This is kept here for historical purposes only and to provide some understanding to why this feature was written.</b></p>
<p>- <a title="Introduction to CCSpriteFrameCache" href="http://www.cocos2d-iphone.org/archives/633" target="_blank">Introduction to CCSpriteFrameCache</a>.<br />
- <a title="How to Animate Sprites in Cocos2D" href="http://getsetgames.com/2010/04/18/how-to-animate-sprites-in-cocos2d/" target="_blank">How to Animate Sprites in Cocos2D</a>.</p>
<p><strong>Background: </strong> We&#8217;re currently developing a game that makes heavy use of Cocos2D for the iPhone / iPod / iPad. I&#8217;m building up to writing a tutorial on how we implemented a system to allow actions to trigger when a given animation frame is reached for a given entity. However, as that&#8217;s not quite there yet &#8211; I wanted to share something a little bit simpler, but something that I consider to be very useful&#8230;</p>
<p><strong>CCAnimationCacheExtensions:</strong> We developed a pretty simple extension for CCAnimationCache that will allow you to build CCAnimations from the information contained in a plist file that contains a list of animation frames and a delay value for a selection of animations. In our model, we created a plist file for each creature, and this plist file is modelled in a specific way, as depicted below;</p>
<div id="attachment_177" class="wp-caption aligncenter" style="width: 590px"><a href="http://www.johnwordsworth.com/wp-content/uploads/2011/07/ccanimation-cache-plist.png"><img class="size-large wp-image-177" title="Sample plist file for adding animations to CCAnimationCache automatically" src="http://www.johnwordsworth.com/wp-content/uploads/2011/07/ccanimation-cache-plist-580x359.png" alt="Image showing an example plist file for adding animations to CCAnimationCache automatically" width="580" height="359" /></a><p class="wp-caption-text">Example plist file for adding animations to CCAnimationCache automatically (click to enlarge)</p></div>
<p>As shown in image of the plist file above, we have a standard plist file with a Dictionary root node. Within that, we have a dictionary named &#8216;animations&#8217; which we will use to store all of the animations that we want to load with our code. In this dictionary, we then hold another dictionary for each animation we want to load, with the key being the name of the animation that we want to load into the cache, and the value of that animation being a another dictionary. Each dictionary at this level represents a <a title="CCAnimation Class Reference" href="http://www.cocos2d-iphone.org/api-ref/1.0.0/interface_c_c_animation.html" target="_blank">CCAnimation</a>, containing a frames array that lists the name of each frame you want to be part of the animation and a delay number which represents the time delay between switching frames.</p>
<p><strong>Important note:</strong> the frames you list in your animations plist file must already exist in the <a title="Introduction to CCSpriteFrameCache" href="http://www.cocos2d-iphone.org/archives/633" target="_blank">CCSpriteFrameCache</a> before you load in this plist file.</p>
<p>Loading this plist file into the <a title="CCAnimationCache Class Reference" href="http://www.cocos2d-iphone.org/api-ref/1.0.0/_c_c_animation_cache_8h_source.html" target="_blank">CCAnimationCache</a> is achieved by calling <strong>[[CCAnimationCache sharedAnimationCache] addAnimationsWithFile:@&#8221;path.plist&#8221;]</strong>. We add this functionality to <a title="CCAnimationCache Class Reference" href="http://www.cocos2d-iphone.org/api-ref/1.0.0/_c_c_animation_cache_8h_source.html" target="_blank">CCAnimationCache</a> without editing any part of the cocos2d library by using an <a href="http://macdevelopertips.com/objective-c/objective-c-categories.html">Objective-C Category</a>, which allows us to add additional methods to a class defined elsewhere without editing the original files (keeping our changes upgrade safe).</p>
<p>The code we use to load these animations is as follows;</p>
<p><strong>CCAnimationCacheExtensions.h</strong></p>
<pre class="brush: plain; title: ; notranslate">
#import
#import &quot;cocos2d.h&quot;

@interface CCAnimationCache (ISExtensions)

-(void)addAnimationsWithDictionary:(NSDictionary *)dictionary;
-(void)addAnimationsWithFile:(NSString *)plist;

@end
</pre>
<p><strong>CCAnimationCacheExtensions.m</strong></p>
<pre class="brush: plain; title: ; notranslate">
#import &quot;CCAnimationCacheExtensions.h&quot;
@implementation CCAnimationCache (ISExtensions)

/** Add animations to the cache from an NSDictionary that contains an 'animations' element at it's root. */
-(void)addAnimationsWithDictionary:(NSDictionary *)dictionary
{
	NSDictionary *animations = [dictionary objectForKey:@&quot;animations&quot;];

	if ( animations == nil ) {
		CCLOG(@&quot;ISCCAnimationCacheExtensions: No animations found in provided dictionary.&quot;);
		return;
	}

	NSArray* animationNames = [animations allKeys];

	for( NSString *name in animationNames ) {
		NSDictionary* animationDict = [animations objectForKey:name];
		NSArray *frameNames = [animationDict objectForKey:@&quot;frames&quot;];
		NSNumber *delay = [animationDict objectForKey:@&quot;delay&quot;];
		CCAnimation* animation = nil;

		if ( frameNames == nil ) {
			CCLOG(@&quot;ISCCAnimationCacheExtensions: Animation '%@' found in dictionary without any frames - cannot add to animation cache.&quot;, name);
			continue;
		}

		NSMutableArray *frames = [NSMutableArray arrayWithCapacity:[frameNames count]];

		for( NSString *frameName in frameNames ) {
			CCSpriteFrame *frame = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:frameName];
			CCLOG(@&quot;ISCCAnimationCacheExtensions: Animation '%@' refers to frame '%@' which is not currently in the CCSpriteFrameCache. This frame will not be added to the animation.&quot;, name, frameName);

			if ( frame != nil ) {
				[frames addObject:frame];
			}
		}

		if ( [frames count] == 0 ) {
			CCLOG(@&quot;ISCCAnimationCacheExtensions: None of the frames for animation '%@' were found in the CCSpriteFrameCache. Animation is not being added to the AnimationCache.&quot;, name);
			continue;
		} else if ( [frames count] != [frameNames count] ) {
			CCLOG(@&quot;ISCCAnimationCacheExtensions: An animation in your dictionary refers to a frame which is not in the CCSpriteFrameCache. Some or all of the frames for the animation '%@' may be missing.&quot;, name);
		}

		if ( delay != nil ) {
			animation = [CCAnimation animationWithFrames:frames delay:[delay floatValue]];
		} else {
			animation = [CCAnimation animationWithFrames:frames];
		}

		[[CCAnimationCache sharedAnimationCache] addAnimation:animation name:name];
	}
}

/** Read an NSDictionary from a plist file and parse it automatically for animations. */
-(void)addAnimationsWithFile:(NSString *)plist
{
	NSString *directory = [plist stringByDeletingLastPathComponent];
	NSString *file = [plist lastPathComponent];
	NSString *path = [[NSBundle mainBundle] pathForResource:file ofType:nil inDirectory:directory];

	NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];

	if ( dict == nil ) {
		CCLOG(@&quot;ISCCAnimationCacheExtensions: Couldn't load animations from plist file.&quot;);
	} else {
		[self addAnimationsWithDictionary:dict];
	}
}

@end
</pre>
<p>The <strong>addAnimationsWithFile:(NSString *)plist</strong> method simply loads a plist file into an NSDictionary and then passes it to the other method, which does the grunt work. The method <strong>addAnimationsWithDictionary:(NSDictionary *)dictionary</strong> does the work of iterating through the relevant elements of the NSDictionary that was read from the plist file and creating a CCAnimation object for each inner dictionary that contains valid &#8216;frames&#8217; (and optionally, a delay).</p>
<p>Playing an animation from the cache is then a case of creating a CCAnimate action and running it on the sprite you want to animate, like so;</p>
<pre class="brush: plain; title: ; notranslate">
CCAnimation *animation = [[CCAnimationCache sharedAnimationCache] animationByName:@&quot;knight-walk-left01.png&quot;];

if ( animation != nil ) {
	CCAction *action = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:animation restoreOriginalFrame:NO]];
	[self.sprite runAction:action];
}
</pre>
<p>I hope you find this useful. If you have any questions about how it works, please don&#8217;t hesitate to get in touch below. </p>
<p>If you&#8217;re interested, here&#8217;s a shot of the code in action, in our upcoming iOS game &#8216;Knight Terrors&#8217;.</p>
<div id="attachment_180" class="wp-caption aligncenter" style="width: 590px"><a href="http://www.johnwordsworth.com/wp-content/uploads/2011/07/knight-terrors-early-screen.png"><img src="http://www.johnwordsworth.com/wp-content/uploads/2011/07/knight-terrors-early-screen-580x406.png" alt="" title="Knight Terrors Early Screenshot" width="580" height="406" class="size-large wp-image-180" /></a><p class="wp-caption-text">An early screenshot of Knight Terrors; please ignore the prototype icons at the bottom of the screen!</p></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.johnwordsworth.com/2011/07/loading-cocos2d-sprite-frame-animations-from-plist-files/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Serializing and De-Serializing android.graphics.Bitmap</title>
		<link>http://www.johnwordsworth.com/2011/06/serializing-and-de-serializing-android-graphics-bitmap/</link>
		<comments>http://www.johnwordsworth.com/2011/06/serializing-and-de-serializing-android-graphics-bitmap/#comments</comments>
		<pubDate>Thu, 09 Jun 2011 16:07:14 +0000</pubDate>
		<dc:creator>John Wordsworth</dc:creator>
				<category><![CDATA[Android Dev]]></category>
		<category><![CDATA[Android Code Snippets]]></category>
		<category><![CDATA[Serializing Bitmap]]></category>

		<guid isPermaLink="false">http://www.johnwordsworth.com/?p=167</guid>
		<description><![CDATA[I recently took it upon myself to write a small application, a bit like Photoshop Express, for Android as a mechanism for learning how to develop on the Android platform. One problem that I stumbled across along was with saving (and subsequently loading) my custom images, which could consist of a number of different layers. ...]]></description>
			<content:encoded><![CDATA[<p>I recently took it upon myself to write a small application, a bit like Photoshop Express, for Android as a mechanism for learning how to develop on the Android platform. One problem that I stumbled across along  was with saving (and subsequently loading) my custom images, which could consist of a number of different layers.</p>
<p>At the heart of my application were a number of layers which consisted of android.graphics.Bitmap layers. I wanted to be able to save (serialize) this data without simply saving the masses of raw binary data from the Bitmap object (which would have been obscenely large).</p>
<p>The following code shows the solution that I came up with. The following code gives an example of how to save a single layer from the application, but as this makes the object serializable, it&#8217;s easy then to save a number of these layers into a single file. </p>
<pre class="brush: plain; title: ; notranslate">
private String title;
private int sourceWidth, currentWidth;
private int sourceHeight, currentHeight;
private Bitmap sourceImage;
private Canvas sourceCanvas;
private Bitmap currentImage;
private Canvas currentCanvas;
private Paint currentPaint; 

/** This container class makes it easy to serialize / de-serialize the raw PNG bytes. */
protected class BitmapDataObject implements Serializable {
    private static final long serialVersionUID = 111696345129311948L;
    public byte[] imageByteArray;
}

/** Included for serialization - write this layer to the output stream. */
private void writeObject(ObjectOutputStream out) throws IOException{
    out.writeObject(title);
    out.writeInt(currentWidth);
    out.writeInt(currentHeight);

    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    currentImage.compress(Bitmap.CompressFormat.PNG, 100, stream);
    BitmapDataObject bitmapDataObject = new BitmapDataObject();
    bitmapDataObject.imageByteArray = stream.toByteArray();

    out.writeObject(bitmapDataObject);
}

/** Included for serialization - read this object from the supplied input stream. */
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{
    title = (String)in.readObject();
    sourceWidth = currentWidth = in.readInt();
    sourceHeight = currentHeight = in.readInt();

    BitmapDataObject bitmapDataObject = (BitmapDataObject)in.readObject();
    Bitmap image = BitmapFactory.decodeByteArray(bitmapDataObject.imageByteArray,
                                               0, bitmapDataObject.imageByteArray.length);

    sourceImage = Bitmap.createBitmap(sourceWidth, sourceHeight, Bitmap.Config.ARGB_8888);
    currentImage = Bitmap.createBitmap(sourceWidth, sourceHeight, Bitmap.Config.ARGB_8888);

    sourceCanvas = new Canvas(sourceImage);
    currentCanvas = new Canvas(currentImage);

    currentPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    thumbnailPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    thumbnailPaint.setARGB(255, 200, 200, 200);
    thumbnailPaint.setStyle(Paint.Style.FILL);
}
</pre>
<p>This solution essentially forces the Bitmap object to compress itself to a ByteArrayOutputStream which we use to store the byte data of the resulting PNG compressed version of the file. There may be a better way to do this, but next up I wrapped this data in a custom object (BitmapDataObject) which can then hook into the standard serializable properties that Java presents to us.</p>
<p>Quite niche I know, but I hope that this saves someone out an hour or two.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnwordsworth.com/2011/06/serializing-and-de-serializing-android-graphics-bitmap/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Overriding NSObject&#8217;s description</title>
		<link>http://www.johnwordsworth.com/2011/01/overriding-nsobjects-description/</link>
		<comments>http://www.johnwordsworth.com/2011/01/overriding-nsobjects-description/#comments</comments>
		<pubDate>Wed, 19 Jan 2011 11:10:25 +0000</pubDate>
		<dc:creator>John Wordsworth</dc:creator>
				<category><![CDATA[iOS Development]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://www.johnwordsworth.com/?p=147</guid>
		<description><![CDATA[NSObject is the base / root class for nearly every hierarchy of classes in Objective-C applications. NSObject provides the basic functionality that you take for granted when using Objective-C, such as providing the ability to retain and release objects. From first time iPhone developers to Objective-C gurus, it&#8217;s hard to deny the usefulness of NSLog() ...]]></description>
			<content:encoded><![CDATA[<p><a title="NSobject Class Reference" href="http://developer.apple.com/library/ios/#DOCUMENTATION/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html" target="_blank">NSObject</a> is the base / root class for nearly every hierarchy of classes in Objective-C applications. NSObject provides the basic functionality that you take for granted when using Objective-C, such as providing the ability to retain and release objects.</p>
<p>From first time iPhone developers to Objective-C gurus, it&#8217;s hard to deny the usefulness of NSLog() and &#8216;gdb&gt; po&#8217; when trying to figure out just which part of your application is causing problems at a given time. NSLog works wonders for outputting strings combined with integers, floats etc. For example, consider the following code and corresponding output.</p>
<div style="border: solid 1px #cccccc; background-color: #f3f3f3; margin-bottom: 14px; padding: 3px;">
<pre>NSLog(@"Integration timestep: %d, x: %f, y: %f", timestep, x_value, y_value);

&gt; 2011-01-19 10:20:30.123 AppName[...] Integration timestep: 10, x: 5.4, y:2.3</pre>
</div>
<p>However, the default implementation doesn&#8217;t really know how to print anything useful for your custom objects. For instance, if you attempt the following, you don&#8217;t really get useful information.</p>
<div style="border: solid 1px #cccccc; background-color: #f3f3f3; margin-bottom: 14px; padding: 3px;">
<pre>NSLog(@"%@", self);

&gt; 2011-01-19 10:20:30.123 AppName[...] &lt;ClassName: 0x000000&gt;</pre>
</div>
<p>The output that you see is simply the class name and the memory address of the object that you&#8217;re logging. This is the default functionality provided by NSObject&#8217;s description, which is what is called when a subclass of NSObject is &#8216;converted to a string&#8217; (which is done by calling the description method).</p>
<p>So, in order to output something more useful, it&#8217;s a good idea to override the NSObject description method. For example, you might want to override the description method for your base game object class to do something like the following;</p>
<div style="border: solid 1px #cccccc; background-color: #f3f3f3; margin-bottom: 14px; padding: 3px;">
<pre>-(NSString *)description
{
  return [NSString stringWithFormat:@"&lt;GameObject: %@, Position: %f, %f&gt;",
                 [self objectID], [self position].x, [self position].y];
}</pre>
</div>
<p>Now, if you call NSLog on a game object, you will be presented with a much nicer string of the form</p>
<p><strong>&lt;GameObject: playerOne, Position: 200, 300&gt;</strong>.</p>
<p>This is even more useful, when you consider that your entities will more than likely be in an array, or dictionary of some form. In this scenario, printing your list of game objects would go from&#8230;</p>
<div style="border: solid 1px #cccccc; background-color: #f3f3f3; margin-bottom: 14px; padding: 3px;">
<pre>&gt; po [self gameObjects]
{
  &lt;GameObject:0x100000&gt;,
  &lt;GameObject:0x101000&gt;,
  &lt;GameObject:0x102000&gt;,
}</pre>
</div>
<p>to&#8230;</p>
<div style="border: solid 1px #cccccc; background-color: #f3f3f3; margin-bottom: 14px; padding: 3px;">
<pre>&gt; po [self gameObjects]
{
  &lt;GameObject: playerOne, Position: 100, 100&gt;
  &lt;GameObject: playerTwo, Position: 600, 300&gt;
  &lt;GameObject: ball, Position: 200, 300&gt;
}</pre>
</div>
<p>While it&#8217;s easy to skip past this stage when building custom objects, it&#8217;s definitely worth the extra 2 minutes per class that it takes to write the description method. Especially when you consider the amount of time it&#8217;ll likely save you down the road when you&#8217;re debugging.</p>
<p><strong>Including Class Name and Address</strong></p>
<p>If you would like to extend the default design and include the class name and address in the object&#8217;s description, then you can do so using the following codes in your NSString format string with the relevant parameter afterwards.</p>
<div style="border: solid 1px #cccccc; background-color: #f3f3f3; margin-bottom: 14px; padding: 3px;">
<pre>"%@": NSStringFromClass([self class])
"%p": self</pre>
</div>
<p>%@ simply represents a placeholder for another string, and we can get the class name for an object as a string by using NSStringFromClass([self class]). %p will be replaced by the address of an object, and so we simply need to pass the corresponding reference to self to include the address of an object this way. </p>
<p>So, for a state in a state machine you might want to output the following information;</p>
<div style="border: solid 1px #cccccc; background-color: #f3f3f3; margin-bottom: 14px; padding: 3px;">
<pre>-(NSString *)description
{
	return [NSString stringWithFormat:@"<%@: %p, ID: %d>",
		NSStringFromClass([self class]), self, [self stateId]];
}</pre>
</div>
<p>Which would output debug information of the form; &lt;ClassName: 0xfa707a0, ID: 1001&gt;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnwordsworth.com/2011/01/overriding-nsobjects-description/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>StarCraft II Crash on Start-Up Fix</title>
		<link>http://www.johnwordsworth.com/2010/08/starcraft-ii-crash-on-start-up-fix/</link>
		<comments>http://www.johnwordsworth.com/2010/08/starcraft-ii-crash-on-start-up-fix/#comments</comments>
		<pubDate>Wed, 18 Aug 2010 20:19:18 +0000</pubDate>
		<dc:creator>John Wordsworth</dc:creator>
				<category><![CDATA[Gaming]]></category>
		<category><![CDATA[Starcraft 2]]></category>
		<category><![CDATA[Starcraft 2 Fixes]]></category>

		<guid isPermaLink="false">http://www.johnwordsworth.com/?p=93</guid>
		<description><![CDATA[I&#8217;m making this post in the hope that it saves someone from the hour of pain that I&#8217;ve just been through with StarCraft II. I was running StarCraft 2 version 1.02 and have been playing it on and off for the last week or so (it&#8217;s great by the way!). I figured I would have ...]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m making this post in the hope that it saves someone from the hour of pain that I&#8217;ve just been through with StarCraft II. I was running StarCraft 2 version 1.02 and have been playing it on and off for the last week or so (it&#8217;s great by the way!). I figured I would have a quick blast before cracking on with some programming this evening, and was annoyed to find it wouldn&#8217;t launch.</p>
<p>The game would load, I would catch a glimpse of the login screen then the game would crash. I&#8217;m running Windows 7, so I tried the following things that have reportedly helped others;</p>
<p>1. &#8216;Running as Administrator&#8217;,</p>
<p>2. Deleting / Renaming the Battle.Net User Folder,</p>
<p>3. Opening up my firewall temporarily,</p>
<p>4. disabling my Anti-virus software,</p>
<p>5. Running a mal-ware scan (AdAware Free) and virus scan.</p>
<p>6. Changing my &#8216;Internet Options -&gt; LAN Settings&#8217; to not use a Proxy / use automatic settings.</p>
<p>After these all failed, I decided to reinstall, which made the problem worse. This time the game would state that I had to download a patch. Upon clicking ok, it would crash and restart &#8211; once again telling me to download the same patch. I didn&#8217;t see the launcher software at all, just a flash of a black screen.</p>
<p>Anyway, if you&#8217;ve tried all of the above and still can&#8217;t get it to work &#8211; I found a fix that works for me.</p>
<p>I launched IE (which I rarely use, as I use Chrome or Safari) and found that it was set to &#8216;Work Offline&#8217;. When I disabled this option, and tried again &#8211; StartCraft II updated and worked fine. Hope it helps someone.</p>
<p><strong>Edit:</strong> If you still can&#8217;t get it to work, then some additional suggestions have been made in the comments section below. They are;</p>
<p>1. It&#8217;s possible that the BattleNet servers are actually down! There were a lot of people recently visiting this post, but unfortunately, it was simply that there was a period when the BNet servers were down. It&#8217;s worth checking Google to see if this is the case. Try disconnecting your Network Cable to run SC2 in Offline mode (Thanks @melsmed).</p>
<p>2. @Komi has reported that a simple reboot of the router might be all that you need!</p>
<p>3. @JamesR404 Makes a good point &#8211; if the client requires a stable network connection, make sure that there isn&#8217;t a firewall / port-block in effect on the router preventing you from connecting to the servers.</p>
<p>4. @Nathan Thanks for the additional suggestion; &#8220;The other day i acquired a virus somehow which changed IE’s proxy settings. If John’s method doesn’t work straight up then check your proxy settings.&#8221;</p>
<p>5. @Denbatte has found that, with Windows 7, if you have a &#8216;Virtual Wifi Miniport&#8217; enabled (in adapters in the network centre) then you may need to disable any virtual ports that exist (right click -&gt; disable). Many thanks for leaving the additional fix idea in the comments.</p>
<p>Thanks all!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnwordsworth.com/2010/08/starcraft-ii-crash-on-start-up-fix/feed/</wfw:commentRss>
		<slash:comments>46</slash:comments>
		</item>
		<item>
		<title>In-App Email through MessageUI Kit</title>
		<link>http://www.johnwordsworth.com/2010/04/iphone-coding-sending-in-application-email/</link>
		<comments>http://www.johnwordsworth.com/2010/04/iphone-coding-sending-in-application-email/#comments</comments>
		<pubDate>Wed, 21 Apr 2010 15:41:58 +0000</pubDate>
		<dc:creator>John Wordsworth</dc:creator>
				<category><![CDATA[iOS Development]]></category>
		<category><![CDATA[In App Messaging]]></category>
		<category><![CDATA[iPhone Code Snippets]]></category>

		<guid isPermaLink="false">http://www.johnwordsworth.com/?p=84</guid>
		<description><![CDATA[I recently added the ability to an iPhone Application that we have been developing to allow the end-user to send email to their contacts directly from our application. This turned out to be trivial using the MessageUI Kit that Apple provide with the iPhone SDK. Here we detail how we implemented this in our application.]]></description>
			<content:encoded><![CDATA[<p>While I recently added the code snippets to my library for <a title="iPhone Code Snippets - Opening Safari, Email and the Phone App" href="http://www.johnwordsworth.com/2010/04/iphone-code-snippets-launching-safari-and-other-apps/" target="_self">launching mail, websites and the phone app</a> from within your iPhone application, this is not always an elegant solution. In certain use cases, the user will want to send an email from within your application and then continue with what they were originally doing &#8211; especially if you have a &#8216;mail to a friend&#8217; button in your game or application.</p>
<p>Luckily, the iPhone OS 3.0 added this functionality. Quite excitingly, similar functionality for in-app SMS messages is coming soon (<a title="What's New with the iPhone OS?" href="http://developer.apple.com/technologies/iphone/whats-new.html" target="_blank">in iPhone OS 4.0</a>), but we won&#8217;t talk about that here.</p>
<p><strong>1. Referencing the MessageUI Framework</strong></p>
<p>First up, we have to ensure that we are linking with the MessageUI Framework, which is the library that will provide the functionality we&#8217;re after. If you&#8217;ve not already got the MessageUI Framework referenced in your project, you&#8217;ll want to right click on &#8216;<strong>Frameworks</strong>&#8216; in your projects &#8216;Groups &amp; Files&#8217; and select <strong>Add -&gt; Existing Frameworks</strong>. Select <strong>MessageUI.framework</strong> and insert it into your project.</p>
<p><strong>2. Call up the MFMailComposeViewController view like any other UIView</strong></p>
<p>Next up you need to create and push to the main navigation controller a fresh <a title="MFMailComposeViewController Class Reference" href="http://developer.apple.com/iphone/library/documentation/MessageUI/Reference/MFMailComposeViewController_class/Reference/Reference.html" target="_blank">MFMailComposeViewController</a>. This will control the in-app email view that will allow the user to complete the remaining details for the email they wish to send and then either beam that email off to the lucky recipients across the internet, or to cancel the operation.</p>
<div style="text-align: center;"><a href="http://www.johnwordsworth.com/wp-content/uploads/2010/04/MFMailComposeViewController.png"><img class="aligncenter size-full wp-image-85" style="border: solid black 2px;" title="MFMailComposeViewController" src="http://www.johnwordsworth.com/wp-content/uploads/2010/04/MFMailComposeViewController.png" alt="In App Email Sending on the iPhone" width="321" height="482" /></a></div>
<p>The example below shows how set a whole host of options on the mail compose view. You don&#8217;t have to set all of these &#8211; things like the Subject and the Recipients are optional, but you will more than likely want to set one or two of these depending on the view that is enabling the user to start a new email.</p>
<p>The code for this will often go in an IBAction method and is as follows</p>
<pre class="brush: cpp; title: ; notranslate">
-(IBAction)sendEmail:(id)sender {
  // Create a new Mail Composer View Controller
  MFMailComposeViewController *mailViewController = [[MFMailComposeViewController alloc] init];
  mailViewController.mailComposeDelegate = self;

  // Optional Configuration Parameters to make life easier for the user
  [mailViewController setSubject:@&quot;Subject&quot;];
  [mailViewController setMessageBody:@&quot;Message Body&quot; isHTML:NO];
  [mailViewController setToRecipients:[NSArray arrayWithObject:@&quot;a@b.com&quot;]];
  [mailViewController setCcRecipients:[NSArray arrayWithObject:@&quot;a@b.com&quot;]];
  [mailViewController setBccRecipients:[NSArray arrayWithObject:@&quot;a@b.com&quot;]];

  // Present the VIew Controller and clean up after ourselves
  [self presentModalViewController:mailViewController animated:YES];
  [mailViewController release];
}
</pre>
<p>Now, we&#8217;ve got an application that shows a compose email view ready for the user to send an email direct from your app. However, there&#8217;s one main problem with the app as it stands &#8211; once you&#8217;ve launched the mail compose view, it&#8217;ll never go away! In order for you to respond when the user has (or hasn&#8217;t) sent an email, and to optionally respond with your own messages depending on whether it worked or not, you&#8217;ll have to implement the <a title="MFMailComposeViewControllerDelegate Protocol Reference" href="http://developer.apple.com/iphone/library/documentation/MessageUI/Reference/MFMailComposeViewControllerDelegate_protocol/Reference/Reference.html" target="_blank">MFMailComposeViewControllerDelegate</a> protocol.</p>
<p><strong>3. Implementing the MFMailComposeViewControllerDelegate Protocol</strong></p>
<p>The third and final step in getting your in app Mail Composer working correctly is to respond to the appropriate delegate protocol. I often find that implementing delegate protocol methods can sometimes be a laborious task &#8211; but you&#8217;re in luck this time, as there is only one method that you have to worry about;</p>
<pre class="brush: cpp; title: ; notranslate">
-(void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
  if ( result == MFMailComposeResultFailed )
  {
    // Sending failed - display an error message to the user.
    NSString* message = [NSString stringWithFormat:@&quot;Error sending email '%@'. Please try again, or cancel the operation.&quot;, [error localizedDescription]];
    UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@&quot;Error Sending Email&quot; message:message delegate:nil cancelButtonTitle:@&quot;Ok&quot; otherButtonTitles:nil];
    [alertView show];
  }
  else
  {
    // If we got here - everything should have gone as the user wanted - dismiss the modal view.
    [self dismissModalViewControllerAnimated:YES];
  }
}
</pre>
<p>There you have it &#8211; 3 easy steps to implementing the MFMailComposeViewController in your iPhone application.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnwordsworth.com/2010/04/iphone-coding-sending-in-application-email/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Implementing a Singleton in Objective-C / iOS</title>
		<link>http://www.johnwordsworth.com/2010/04/iphone-code-snippet-the-singleton-pattern/</link>
		<comments>http://www.johnwordsworth.com/2010/04/iphone-code-snippet-the-singleton-pattern/#comments</comments>
		<pubDate>Sat, 17 Apr 2010 22:27:09 +0000</pubDate>
		<dc:creator>John Wordsworth</dc:creator>
				<category><![CDATA[iOS Development]]></category>
		<category><![CDATA[iPhone Code Snippets]]></category>
		<category><![CDATA[iPhone SDK]]></category>

		<guid isPermaLink="false">http://www.johnwordsworth.com/?p=73</guid>
		<description><![CDATA[There are many pages of discussions around the internet about whether or not you should use global variables in your applications. I&#8217;m not going to to into the depths of these discussions, but I have come to live by the following ethos when it comes to using global variables in my application; Use them sparingly; ...]]></description>
			<content:encoded><![CDATA[<p>There are many pages of discussions around the internet about whether or not you should use global variables in your applications. I&#8217;m not going to to into the depths of these discussions, but I have come to live by the following ethos when it comes to using global variables in my application;</p>
<p><strong>Use them sparingly;</strong> Having too many global variables floating around makes it very hard to keep track of what&#8217;s going on. I never use more than one global object for each logical section of my code &#8211; even if that object contains a handful of other objects from that section.</p>
<p><strong>But you do sometimes need them; </strong>I once wrote a small game where I decided not to use my own globals at all. Truth be told, I ended up with a bit of a mess &#8211; a large number of similar constructors with a numbers of parameters to link my objects together. Sure, the units were technically separate and didn&#8217;t rely on each other &#8211; but the reality was, that when you get deep enough into your code &#8211; some classes are only ever going to be used in this project (view controllers etc).</p>
<p><strong>Use them when it&#8217;s applicable;</strong> Generally, global variables are applicable in situations when you&#8217;ve got an object / class of which you are only ever going to need one of them <strong>and</strong> they don&#8217;t logically sit as a child of one single part of the application. For instance, the &#8216;application&#8217; object in some languages &#8211; where the object represents the running application.</p>
<p><strong>So, Singleton Eh?</strong></p>
<p>The Singleton model is often used to instantiate just one instance of a class which doesn&#8217;t allow a second instance of that same class to be loaded anywhere in the application. Some implementations will throw an exception if you try to create a second instance of the class, some will create the singleton for you when you first try to access it, and some will even let you create other instances if you want, but will always manage a &#8216;single shared instance&#8217; for you. Many of the core Apple classes follow this pattern, such as [UIApplication sharedApplication].</p>
<p>Anyway, Apple do a very good job (naturally) of providing a <a title="Apple Singleton Model Example" href="http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/CocoaObjects.html#//apple_ref/doc/uid/TP40002974-CH4-SW32" target="_blank">good example of the Singleton model</a>. The following code is rather similar to the Apple example, but it also includes what you should have in the header file. It is also a stable part of any library of code snippets, so it has to be here really!</p>
<p><strong>SingletonClass.h</strong></p>
<pre class="brush: cpp; title: ; notranslate">
#import &lt;Foundation/Foundation.h&gt;

@interface SingletonClass : NSObject {

}

+ (id)sharedInstance;
@end
</pre>
<p><strong>SingletonClass.m</strong></p>
<pre class="brush: cpp; title: ; notranslate">
#import &quot;SingletonClass.h&quot;

@implementation SingletonClass

static SingletonClass *sharedInstance = nil;

// Get the shared instance and create it if necessary.
+ (SingletonClass *)sharedInstance {
    if (sharedInstance == nil) {
        sharedInstance = [[super allocWithZone:NULL] init];
    }

    return sharedInstance;
}

// We can still have a regular init method, that will get called the first time the Singleton is used.
- (id)init
{
    self = [super init];

    if (self) {
        // Work your initialising magic here as you normally would
    }

    return self;
}

// Your dealloc method will never be called, as the singleton survives for the duration of your app.
// However, I like to include it so I know what memory I'm using (and incase, one day, I convert away from Singleton).
-(void)dealloc
{
    // I'm never called!
    [super dealloc];
}

// We don't want to allocate a new instance, so return the current one.
+ (id)allocWithZone:(NSZone*)zone {
    return [[self sharedInstance] retain];
}

// Equally, we don't want to generate multiple copies of the singleton.
- (id)copyWithZone:(NSZone *)zone {
    return self;
}

// Once again - do nothing, as we don't have a retain counter for this object.
- (id)retain {
    return self;
}

// Replace the retain counter so we can never release this object.
- (NSUInteger)retainCount {
    return NSUIntegerMax;
}

// This function is empty, as we don't want to let the user release this object.
- (oneway void)release {

}

//Do nothing, other than return the shared instance - as this is expected from autorelease.
- (id)autorelease {
    return self;
}

@end
</pre>
<p>There you go &#8211; copy and paste this into your new project, rename the interface and implementations and you&#8217;re done &#8211; a ready to use Singleton in your project.</p>
<p><strong>Making the creation of your singleton thread safe</strong></p>
<p><a href="http://blog.jh-lim.com">Jiunn Harr</a> wrote a great blog post on making the creation of your Singleton thread safe. In the above example, it is possible that your Singleton&#8217;s init method could be called more than once, if sharedInstance was called for the first and second time concurrently on different threads. In order to by-pass this problem, you can replace the sharedInstance method above with the following;</p>
<pre class="brush: cpp; title: ; notranslate">
+ (SingletonClass *)sharedInstance {
    if (nil != sharedInstance) {
        return sharedInstance;
    }

    static dispatch_once_t pred;        // Lock
    dispatch_once(&amp;pred, ^{             // This code is called at most once per app
        singleton = [[SingletonClass alloc] init];
    });

    return singleton;
}
</pre>
<p>Note. This doesn&#8217;t make all calls on your Singleton thread safe &#8211; it simply ensures that the creation of your Singleton is thread safe. This code uses Grand Central Dispatch (Cocoa and iOS4+). To read more about how this works, and why you should consider using it &#8211; check out <a href="http://blog.jh-lim.com/2011/09/implementing-a-singleton-in-ios/">Jiunn Haur&#8217;s great blog post</a> on the subject.</p>
<p><strong>Using the Singleton Class</strong></p>
<p>The above code creates the framework for a Singleton class. You can almost ignore the majority of the code above and no go about setting up your own variables and methods for use in your singleton class. It&#8217;s worth bearing in mind that when you first attempt to you access your Singleton, it will be created for you, and from that point onwards &#8211; it will probably reside in memory for the remainder of your application&#8217;s lifecycle. Because of this, you might want to be careful about memory usage and ensure that classes inside your singleton element are tidy.</p>
<p>Accessing your Singleton class from your code is then simply a matter of using the <em>+(SingletonClass*)sharedInstance</em> to get a pointer to the one instance of the singleton class that exists in your application. You can do this anywhere in your code and you would do this for the above class by doing something like the following;</p>
<pre class="brush: plain; title: ; notranslate">
SingletonClass* sharedSingleton = [SingletonClass sharedInstance];
[sharedSingleton callAMethod];
</pre>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnwordsworth.com/2010/04/iphone-code-snippet-the-singleton-pattern/feed/</wfw:commentRss>
		<slash:comments>35</slash:comments>
		</item>
		<item>
		<title>Launch Safari with UIApplication openURL</title>
		<link>http://www.johnwordsworth.com/2010/04/iphone-code-snippets-launching-safari-and-other-apps/</link>
		<comments>http://www.johnwordsworth.com/2010/04/iphone-code-snippets-launching-safari-and-other-apps/#comments</comments>
		<pubDate>Sat, 17 Apr 2010 20:48:32 +0000</pubDate>
		<dc:creator>John Wordsworth</dc:creator>
				<category><![CDATA[iOS Development]]></category>
		<category><![CDATA[iPhone SDK]]></category>
		<category><![CDATA[Launching Safari]]></category>

		<guid isPermaLink="false">http://www.johnwordsworth.com/?p=64</guid>
		<description><![CDATA[Having devoted much of my time over the last few months developing for the iPhone, I thought it was time to start collecting a small library of useful code snippets here on my blog. I&#8217;m mostly posting these for my own use, so that I don&#8217;t have to keep searching Google to keep finding the ...]]></description>
			<content:encoded><![CDATA[<p>Having devoted much of my time over the last few months developing for the iPhone, I thought it was time to start collecting a small library of useful code snippets here on my blog. I&#8217;m mostly posting these for my own use, so that I don&#8217;t have to keep searching <a title="It's Google, of course..." href="http://www.google.com" target="_blank">Google</a> to keep finding the useful bits of code. However, I&#8217;ll try to make the posts as accessible as possible, with some explanation where necessary.</p>
<p><strong>Launching Safari from within an iPhone App</strong></p>
<p>The <a title="openURL Method Reference" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIApplication_Class/Reference/Reference.html#//apple_ref/occ/instm/UIApplication/openURL:" target="_blank">openURL</a> method of <a title="UIApplication Class Reference" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIApplication_Class/Reference/Reference.html" target="_blank">UIApplication</a> is a very useful and valuable method. It provides a quick and simple way to leave the current application and load up the web browser, the email application or even the phone application. It also provides a way for you to set the &#8216;default&#8217; data, such as the start page in safari, or the email recipient for mail.</p>
<p>Using the function to launch Safari with a specific URL is simple, it requires barely any code. The following example shows how one would use <a title="openURL Method Reference" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIApplication_Class/Reference/Reference.html#//apple_ref/occ/instm/UIApplication/openURL:" target="_blank">openUrl</a> to launch Safari having clicked a button.</p>
<pre class="brush: cpp; title: ; notranslate">-(IBAction)linkButtonClick:(id)sender {
NSString* launchUrl = @&amp;amp;amp;quot;http://www.johnwordsworth.com/&amp;amp;amp;quot;;
[[UIApplication sharedApplication] openURL:[NSURL URLWithString: launchUrl]];
}</pre>
<p><strong>Launching Mail, the Phone or SMS</strong></p>
<p>Launching the mail client, phone or the SMS client is equally as simple. The <a title="openURL Method Reference" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIApplication_Class/Reference/Reference.html#//apple_ref/occ/instm/UIApplication/openURL:" target="_blank">openURL</a> method examines the first few characters of your URL and then uses this information to determine what information you have provided. It then does it&#8217;s best to enact what you have requested.</p>
<p>The following functions give you a quick and easy way to launch the relevant apps quickly and easily.</p>
<pre class="brush: cpp; title: ; notranslate">// Launch the email client with mailto://[recipient]
-(BOOL)launchMailWithRecipient:(NSString *)recipient {
NSString* launchUrl = [NSString stringWithFormat:@&amp;amp;amp;quot;mailto://%@&amp;amp;amp;quot;, recipient];
return [[UIApplication sharedApplication] openURL:[NSURL URLWithString: launchUrl]];
}</pre>
<pre class="brush: cpp; title: ; notranslate">// Launch the phone with tel://[number]
-(BOOL)launchPhoneWithNumber:(NSString *)number {
NSString* launchUrl = [NSString stringWithFormat:@&amp;amp;amp;quot;tel://%@&amp;amp;amp;quot;, number];
return [[UIApplication sharedApplication] openURL:[NSURL URLWithString: launchUrl]];
}</pre>
<pre class="brush: cpp; title: ; notranslate">// Launch the SMS client with sms:[number]
-(BOOL)launchSMSWithNumber:(NSString *)number {
NSString* launchUrl = [NSString stringWithFormat:@&amp;amp;amp;quot;sms:%@&amp;amp;amp;quot;, number];
return [[UIApplication sharedApplication] openURL:[NSURL URLWithString: launchUrl]];
}</pre>
<p><strong>But the iPod doesn&#8217;t have a phone!?</strong></p>
<p>That&#8217;s right &#8211; there&#8217;s something we&#8217;ve not yet touched upon, and that&#8217;s the fact that <a title="openURL Method Reference" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIApplication_Class/Reference/Reference.html#//apple_ref/occ/instm/UIApplication/openURL:" target="_blank">openURL</a> returns a boolean value. This value lets you know whether or not the operation completed successfully. Obviously, if it did &#8211; then you&#8217;d better clean up your App pretty quick as it&#8217;s not going to be in the foreground for much longer! However, more usefully, it allows you to handle the case when the supported operation is not permitted.</p>
<p>For instance, if you&#8217;re hoping to loading up the phone app on an iPod Touch, then it&#8217;s not going to work. In this case, you might want to popup a <a title="UIAlertView Class Reference" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIAlertView_Class/UIAlertView/UIAlertView.html" target="_blank">UIAlertView</a> to let the user know that it&#8217;s not going to work. If you&#8217;re really working hard towards a friendly user interface, then you can use the <a title="canOpenUrl Method Reference" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIApplication_Class/Reference/Reference.html#//apple_ref/occ/instm/UIApplication/canOpenURL:" target="_blank">canOpenUrl</a> method to check this out without actually leaving the application. For instance, if <a title="canOpenUrl Method Reference" href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIApplication_Class/Reference/Reference.html#//apple_ref/occ/instm/UIApplication/canOpenURL:" target="_blank">canOpenUrl</a> returns false, then you could disable the links or buttons that would otherwise launch the phone or SMS application.</p>
<p>How would you do that?</p>
<pre class="brush: cpp; title: ; notranslate">-(BOOL)doesDeviceHaveAPhone {
NSString* launchUrl = @&amp;amp;amp;quot;tel://0&amp;amp;amp;quot;;
return [[UIApplication sharedApplication] canOpenUrl:[NSURL URLWithString: launchUrl]];
}</pre>
<p>I&#8217;ll leave you to think about the other cunning things that you can do, such as launching with an http url that links directly to a google map / youtube video or custom Google search string. Anyhow, when combined with other elements of a productivity app, this can be quite useful! Enjoy.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnwordsworth.com/2010/04/iphone-code-snippets-launching-safari-and-other-apps/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Vendetta Online Onyx Skin</title>
		<link>http://www.johnwordsworth.com/2010/04/vendetta-online-onyx-skin/</link>
		<comments>http://www.johnwordsworth.com/2010/04/vendetta-online-onyx-skin/#comments</comments>
		<pubDate>Sun, 04 Apr 2010 23:46:10 +0000</pubDate>
		<dc:creator>John Wordsworth</dc:creator>
				<category><![CDATA[Gaming]]></category>
		<category><![CDATA[MMORPGs]]></category>

		<guid isPermaLink="false">http://www.johnwordsworth.com/?p=52</guid>
		<description><![CDATA[Following on from my previous post about Vendetta Online, I&#8217;ve spent a large portion of my day working on a new skin for Vendetta Online. I&#8217;ve always found the default skin fairly mediocre. While it&#8217;s nice, it doesn&#8217;t scale overly well to my 1080p monitor. Now, in the modern day, it&#8217;s not unusual to have ...]]></description>
			<content:encoded><![CDATA[<p>Following on from my previous post about Vendetta Online, I&#8217;ve spent a large portion of my day working on a new skin for Vendetta Online. I&#8217;ve always found the default skin fairly mediocre. While it&#8217;s nice, it doesn&#8217;t scale overly well to my 1080p monitor. Now, in the modern day, it&#8217;s not unusual to have a high-resolution monitor, and to have the radar sprites aliased and upscaled to fit the screen was my equivalent of scraping nails down a blackboard.</p>
<p>So, instead of bitching about it, I thought I would &#8216;simply&#8217; fix it. Now, I leafed through a couple of other people&#8217;s skins, browed through the empty &#8216;how to make a skin&#8217; wiki page and thought; &#8220;It&#8217;s not going to be easy, but I&#8217;ll give it a try.&#8221;. Now, if you&#8217;ve ever had any experience re-skinning an application before, you&#8217;ll know that it&#8217;s never as easy as you think it should be. Vendetta Online is, unfortunately, no exception.</p>
<p>I thought it would have been nice if the skins consisted of an XML file that would allow you to set the text colors and provide solid borders without the need for producing graphics, but I can also see how this is low on the priority scales for the developers. Anyway, with over 100 files to produce my head is already turning around ideas of how to produce a piece of software to make the whole process easier, but for now, here are some screenshots of the skin that I have been working on.</p>
<p style="text-align: center;"><a href="http://www.johnwordsworth.com/wp-content/uploads/2010/04/onyx-skin-01.jpg"><img class="size-medium wp-image-53 aligncenter" title="Vendetta Skin Onyx Screenshot" src="http://www.johnwordsworth.com/wp-content/uploads/2010/04/onyx-skin-01-300x173.jpg" alt="Vendetta Skin Onyx Screeshot" width="300" height="173" /></a></p>
<p style="text-align: center;">(Click images to enlarge)</p>
<p style="text-align: center;"><a href="http://www.johnwordsworth.com/wp-content/uploads/2010/04/onyx-skin-02.jpg"><img class="aligncenter size-medium wp-image-54" title="Vendetta Online Skin Onyx Screenshot" src="http://www.johnwordsworth.com/wp-content/uploads/2010/04/onyx-skin-02-300x173.jpg" alt="Vendetta Online Skin Onyx Screenshot" width="300" height="173" /></a></p>
<p style="text-align: center;"><a href="http://www.johnwordsworth.com/wp-content/uploads/2010/04/onyx-skin-03.jpg"><img class="aligncenter size-medium wp-image-55" title="Vendetta Online Skin Onyx Screenshot" src="http://www.johnwordsworth.com/wp-content/uploads/2010/04/onyx-skin-03-300x173.jpg" alt="Vendetta Online Skin Onyx Screenshot" width="300" height="173" /></a></p>
<p style="text-align: left;">As you can see, there are a few bits that need some extra work. Most importantly, the HUD elements are still plagued by an aliasing problem that was the main reason that I wanted to write this skin. However, this time, it&#8217;s not the radar, but the central HUD elements. Anyway &#8211; I&#8217;ll find a good compromise, get it all packaged up, and hopefully release it out to the community at some point soon.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnwordsworth.com/2010/04/vendetta-online-onyx-skin/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Vendetta Online Introduction</title>
		<link>http://www.johnwordsworth.com/2010/04/vendetta-online-introduction/</link>
		<comments>http://www.johnwordsworth.com/2010/04/vendetta-online-introduction/#comments</comments>
		<pubDate>Sun, 04 Apr 2010 23:33:49 +0000</pubDate>
		<dc:creator>John Wordsworth</dc:creator>
				<category><![CDATA[Gaming]]></category>
		<category><![CDATA[MMORPGs]]></category>

		<guid isPermaLink="false">http://www.johnwordsworth.com/?p=47</guid>
		<description><![CDATA[I've been playing Vendetta Online for a couple of months now in the little spare time I have, and I wanted to put a little bit of background onto my blog before launching into some screenshots of the skin that I'm working on for this game.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been playing <a title="Vendetta Online - Cross-Platform Space MMORPG" href="http://www.vendetta-online.com" target="_blank">Vendetta Online</a> on and off now for a couple of months. For those of you not in the know, Vendetta Online is a space based MMORPG that runs on Windows, OSX and Linux. It offers an experience that is vastly different to <a title="EVE Online - Space Strategy MMORPG" href="http://www.eveonline.com/" target="_self">EVE Online</a>. Where EVE offers a third person &#8216;point and click&#8217; type space experience, Vendetta places you in the cockpit of your chosen space vehicle, battling face to face with bots and players across a variety of missions.</p>
<div style="float: left; padding: 0px 10px 10px 0px;"><a href="http://www.johnwordsworth.com/wp-content/uploads/2010/04/dump0182.jpg"><img class="alignleft size-medium wp-image-48" title="Vendetta Online Screenshot" src="http://www.johnwordsworth.com/wp-content/uploads/2010/04/dump0182-300x225.jpg" alt="Vendetta Online Screenshot" width="300" height="225" /></a></div>
<p>Another important difference, is that Vendetta Online is produced by only 4 people. In my opinion, this has had 2 massive effects on the game. First of all, unfortunately, it means that the game is lacking a little in scope. It&#8217;s not easy to find truly unique missions as the focus seems to have been on the core &#8216;learning the game&#8217; and &#8216;generic always there missions&#8217; to date. This means that the awesome history and thought that&#8217;s gone into the world doesn&#8217;t get to shine through. Also, the graphics aren&#8217;t quite up to EVE&#8217;s standards. Don&#8217;t get me wrong, they&#8217;re great for a team of 4, and produce a wonderful experience, but it&#8217;s unfortunate that they have to sit next to EVE in a comparison.</p>
<p>The second effect on the otherhand, is absolutely amazing. Being led by only a team of 4, and having a tight-nit community has led to some innovation in the MMORPG genre. The game has a Player Contribution Corp; a group of players who have access to a set of tools and guides for contributing missions, plugins and skins to the game. Some of the community made plug-ins really fill those gaps that the development team simply haven&#8217;t had time to plug yet.</p>
<p>Being able to contribute to a live MMORPG is really appealing to me. As someone who is just starting his career in the gaming industry, I love the idea of being able to join a friendly and ambitious community, put a handful of hours into a mission, skin or plug-in and see it in action in a real live game. It was this that spurned me on to write this post. I&#8217;ve started work on a new skin for the engine that I hope will help the engine shine a little more on my monitor, and wanted to share some thoughts about my experience.</p>
<p>The bottom line is this; If you&#8217;re looking for an MMORPG with a small yet friendly player-base that will allow you to contribute ideas and suggestions to the development of the game, then Vendetta Online is definitely something you should try out. I&#8217;m not going to lie &#8211; the first 30-60 minutes might be a little different to your regular MMORPG experience &#8211; it won&#8217;t be quite as shiny, but you will pretty quickly get to witness the community first hand. Hell, they&#8217;ve got an 8 hour trial (that&#8217;s 8 hours in game, you can spread it over a few weeks if you wish) &#8211; so why not give it a shot?</p>
<p><a title="Download the Vendetta Online Client" href="http://www.vendetta-online.com/x/download" target="_blank">Download the Vendetta Online Client Here</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnwordsworth.com/2010/04/vendetta-online-introduction/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New Blog Design</title>
		<link>http://www.johnwordsworth.com/2010/04/new-blog-design/</link>
		<comments>http://www.johnwordsworth.com/2010/04/new-blog-design/#comments</comments>
		<pubDate>Sun, 04 Apr 2010 01:44:53 +0000</pubDate>
		<dc:creator>John Wordsworth</dc:creator>
				<category><![CDATA[Site Updates]]></category>

		<guid isPermaLink="false">http://www.johnwordsworth.com/?p=44</guid>
		<description><![CDATA[A good evening to you all from behind a warm mug of tea, late at night here in the UK. If you&#8217;ve visited here before, you may have noticed that things are looking a litte bit different here today. This fantastic evening marks the begining of my revisited blog. There is still much for me ...]]></description>
			<content:encoded><![CDATA[<p>A good evening to you all from behind a warm mug of tea, late at night here in the UK. If you&#8217;ve visited here before, you may have noticed that things are looking a litte bit different here today.</p>
<p>This fantastic evening marks the begining of my revisited blog. There is still much for me to do on the blog design before I could consider it done (adding dates into the template in a friendly fashion to start with). Anyhow, this is all leading up to some posts about XNA programming from dicussions that I had a while ago over at <a title="XNA Chat" href="http://xnachat.com" target="_blank">xnachat.com</a>. Anyhow, it&#8217;s late here and there&#8217;s much sleep to be had.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnwordsworth.com/2010/04/new-blog-design/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>XNA 3.0 &#8211; Reading Text Files on the Xbox</title>
		<link>http://www.johnwordsworth.com/2009/01/xna-30-reading-text-files-on-the-xbox/</link>
		<comments>http://www.johnwordsworth.com/2009/01/xna-30-reading-text-files-on-the-xbox/#comments</comments>
		<pubDate>Fri, 02 Jan 2009 12:42:35 +0000</pubDate>
		<dc:creator>John Wordsworth</dc:creator>
				<category><![CDATA[XNA Programming]]></category>
		<category><![CDATA[Reading Text Files]]></category>
		<category><![CDATA[Xbox Community Games]]></category>
		<category><![CDATA[Xbox XNA]]></category>
		<category><![CDATA[XNA]]></category>

		<guid isPermaLink="false">http://www.johnwordsworth.com/blog/?p=28</guid>
		<description><![CDATA[We are making strong progress on an XNA Community Game title that we are working on and I have just spend a good 30 minutes trying to figure this out. Hence, I'm writing this as a future reference for myself and in the hope that it might help any coders out there trying to achieve the same thing.]]></description>
			<content:encoded><![CDATA[<p>We are making strong progress on an XNA Community Game title that we are working on and I have just spend a good 30 minutes trying to figure this out. Hence, I&#8217;m writing this as a future reference for myself and in the hope that it might help any coders out there trying to achieve the same thing.</p>
<p><strong>The Problem</strong></p>
<p>Our game is relatively simple and we would like to define the stages that the player progresses through in a plain text file. While it&#8217;s a very simple task to read a text file in C#, I initially had problems assuming that loading a new StreamReader on the the Xbox like so <strong>StreamReader(&#8220;LevelIndex.txt&#8221;);</strong> would load up a text file in the same directory as my executable. Not the case &#8211; it turns out that, as the Xbox doesn&#8217;t really follow a directory structure like a PC, this doesn&#8217;t work.</p>
<p><strong>The Solution</strong></p>
<p>The solution is also relatively simple, but not east to find &#8211; as it&#8217;s one of those things that you either know how to do or not. There are 2 important things to note before jumping directly into a code listing.</p>
<p><strong>1. StorageContainer.TitleLocation:</strong> In order to construct the file path that you will be feeding into a StreamReader, you must prefix your path with this property. To load up the file &#8216;LevelIndex.txt&#8217;, which resides in the root directory of your solution, you must construct the path as follows; <strong>String fullPath = StorageContainer.TitleLocation + &#8220;LevelIndex.txt&#8221;;</strong></p>
<p><strong>2. Build Action (None), Copy to Output Directory (Copy if Newer):</strong> As your text file is not going to be processed by the Content Processor, you need to tell Visual Studio what should be done with your text file. For my project, I dragged and dropped the text file into my Solution (but NOT in the Content directory). The text file sits alongside your .cs files (although, could reside in a folder). Then, you must change the properties of the text so that Build Action is set to &#8216;None&#8217; and Copy to Output Directory is set to &#8216;Copy if Newer&#8217;. This ensures that Visual Studio doesn&#8217;t try to compile the file as code or include it in your Content repository. It will simply copy the text file to the TitleLocation of your game &#8211; just what you want so that you can read it from within your title.</p>
<p><strong>Code Listing</strong></p>
<p>The following code listing shows how we have implemented a simple text file reader for an Xbox XNA Project;</p>
<pre>function String[] readStageTitles( String filePath ) {
  ArrayList stageTitles = new ArrayList();
  String[] returnData = null;

  // Both Windows and Xbox - Ensures we are looking in the game's folder.
  String StageIndexPath = StorageContainer.TitleLocation + "\\" + file;

  try
  {
    StreamReader streamReader = new StreamReader(StageIndexPath);
    String line;

    while ((line = streamReader.ReadLine()) != null)
    {
      String[] data = line.Split(';');

      if ( data.Length == 2 ) {
        stageTitles.Add(data[1]);
      }
    }

    streamReader.Close();
  }
  catch( Exception ex )
  {
    // Do things here incase it can't read the file
  }

  returnData = (String[])stageTitles.ToArray( typeof(String) );
  return returnData;
}</pre>
<p>Hope this helps someone out there.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnwordsworth.com/2009/01/xna-30-reading-text-files-on-the-xbox/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Quick Fix for Really Slow Remote Desktop to Vista (X64)</title>
		<link>http://www.johnwordsworth.com/2008/10/quick-fix-for-really-slow-remote-desktop-to-vista-x64/</link>
		<comments>http://www.johnwordsworth.com/2008/10/quick-fix-for-really-slow-remote-desktop-to-vista-x64/#comments</comments>
		<pubDate>Sat, 04 Oct 2008 18:41:25 +0000</pubDate>
		<dc:creator>John Wordsworth</dc:creator>
				<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.johnwordsworth.com/blog/?p=26</guid>
		<description><![CDATA[I have spent a few hours today trying to use a Remote Desktop Connection from my Macbook to my Vista X64 machine on the same local network. After countless hits of exceptionally slow speed, I realised that it wasn&#8217;t network bandwidth or even heavy CPU usage that was slowing down my experience. After a few ...]]></description>
			<content:encoded><![CDATA[<p>I have spent a few hours today trying to use a Remote Desktop Connection from my Macbook to my Vista X64 machine on the same local network. After countless hits of exceptionally slow speed, I realised that it wasn&#8217;t network bandwidth or even heavy CPU usage that was slowing down my experience.</p>
<p>After a few searches on Google and many failed attempts, I found that the following command instantly fixed my problem;</p>
<p><strong>netsh interface tcp set global autotuninglevel=disabled</strong></p>
<p>I&#8217;m afraid I have no real idea what other impact this might have on your machine / server. I understand that this disables the built in network &#8216;tuning&#8217; that Vista uses to try to improve your bandwidth usage so that all software on your machine is guaranteed a solid minimum Quality of Service (QoS). I suspect that it&#8217;ll have no noticable impact at all, it&#8217;ll just perform more like XP than Vista (which was fine).</p>
<p>If it does screw things up, you can reverse this action by;</p>
<p><strong>netsh interface tcp set global autotuninglevel=normal</strong></p>
<p>You&#8217;ll have to run this from a cmd.exe shell and will probably need to run cmd.exe with the &#8216;Run as Administrator&#8230;&#8217; command. I have UAC disabled, so it runs fine anyway. You should just get a simple &#8216;Ok&#8217; response from the software if it&#8217;s run ok.</p>
<p>I hope that this helps some people. It&#8217;s been running perfectly fine ever since.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnwordsworth.com/2008/10/quick-fix-for-really-slow-remote-desktop-to-vista-x64/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Print Screen on a Mac</title>
		<link>http://www.johnwordsworth.com/2008/08/print-screen-on-a-mac/</link>
		<comments>http://www.johnwordsworth.com/2008/08/print-screen-on-a-mac/#comments</comments>
		<pubDate>Tue, 19 Aug 2008 10:13:03 +0000</pubDate>
		<dc:creator>John Wordsworth</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[mac tips]]></category>
		<category><![CDATA[OSX]]></category>

		<guid isPermaLink="false">http://www.johnwordsworth.com/blog/?p=24</guid>
		<description><![CDATA[Some tips about the plethora of ways to capture an image of the desktop (or parts of the desktop) on a Mac Book / Apple's OSX.]]></description>
			<content:encoded><![CDATA[<p>As many of you are aware, I&#8217;ve recently converted to a mac through the purchase of a Mac Book laptop. I also tried to convert my desktop life, but after some horrible experiences with the screens on the new iMac&#8217;s, I&#8217;ve decided that will have to come much later down the road in our business when we can afford a Mac Pro for my desk (where I get personal control over my desktop).</p>
<p>This week, I&#8217;ve mostly been playing with the Print Screen options / Screen Capture options. Previously, I&#8217;ve only used a couple of the plethora of screen capture options that OSX offers, but I thought it time to get a definitive list of the (hard to remember) key combinations available, mostly for my own reference.</p>
<p>So, putting Windows to shame, you can actually save a screen capture as a JPEG file with a mouse click. This would be a great addition to windows and would definitely stop me from receiving emails that are 5Mb with 2 BMP screen caps in that I&#8217;ve been receiving a lot of recently. An overview of the commands are;</p>
<p><strong>Saving a Screen Capture Direct to a JPEG File</strong></p>
<p>⌘ ⇧ 3: Capture the entire screen to a jpeg file on the desktop.</p>
<p>⌘ ⇧ 4 (Followed by Drag): Capture the selected area of the screen to a jpeg file on the desktop.</p>
<p>⌘ ⇧ 4 (Then Spacebar, Then click on a window): Capture selected window (and sometimes a border) to a jpeg file on the desktop.</p>
<p><strong>Saving a Screen Capture to the Clipboard</strong></p>
<p>⌘ ⇧ Ctrl + 3: Capture the entire screen to the clipboard.</p>
<p>⌘ ⇧ Ctrl + 4 (Followed by Drag): Capture the selected area of the screen to the clipboard.</p>
<p>⌘ ⇧ Ctrl + 4 (Then Spacebar, Then click on a window): Capture selected window (and sometimes a border) to the clipboard.</p>
<p><strong>Using these Commands</strong></p>
<p>It&#8217;s important to push all of the auxiliary keys for your command before pushing the number key. So if you want to capture the screen to the clipboard, ensure that you are holding down Cmd (⌘), Shift(⇧) and Ctrl first, and then hit the 3 key. If you are copying to the clipboard, OSX should still make the camera-snap sound effect, but will not leave a file on your desktop. You can then paste the item from your clipboard into a Pages or Keynote document.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnwordsworth.com/2008/08/print-screen-on-a-mac/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Mono &#8211; Running .NET Applications on OSX/Linux</title>
		<link>http://www.johnwordsworth.com/2008/08/mono-running-net-applications-on-osxlinux/</link>
		<comments>http://www.johnwordsworth.com/2008/08/mono-running-net-applications-on-osxlinux/#comments</comments>
		<pubDate>Sat, 16 Aug 2008 18:48:35 +0000</pubDate>
		<dc:creator>John Wordsworth</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Mono]]></category>
		<category><![CDATA[OSX]]></category>

		<guid isPermaLink="false">http://www.johnwordsworth.com/blog/?p=19</guid>
		<description><![CDATA[Mono allows users of Linux and OSX to run .NET Applications written in C# and Visual Basic on their computers. While not perfect - it opens up a whole batch of applications to users of Linux and OSX.]]></description>
			<content:encoded><![CDATA[<p>This may be old news to some people, but I have recently found the power of a piece of software called <a title="Mono Project" href="http://www.mono-project.com/" target="_blank">Mono</a>. Now, it actually takes quite a lot of research and a bit of experimentation to realise just how powerful Mono is. Nowhere on their landing page does it tell you that it lets you run .NET Managed EXE files compiled for windows on Linux and even OSX.</p>
<p>I&#8217;m not sure how many of you are aware, but Microsoft&#8217;s .NET languages such as Visual Basic and C# don&#8217;t actually compile into windows specific executable code but they instead get compiled into an &#8216;intermediate&#8217; code similar to Java. This is why you are required to download 80Mb of .NET Framework files to run them on XP.</p>
<p>So, what the clever guys on the Mono Project have done is rewrite the .NET Framework so that it runs on other operating systems. That means that you are able to run software that was compiled for Windows as .NET Managed Code in other operating systems as if it were a native application. Now the system is far from perfect, so you&#8217;re not able to just pick any application and guarantee it will work &#8211; but the project is improving all the time and making more and more programs compatible.</p>
<p>Again, something which is not stated, is how easy this is. Download the Mono application for your machine. And then type: <strong>&#8216;mono MyApplication.exe&#8217; </strong>and wait for the application to run. Hassle free (when it works).</p>
<p>While this may not seem significant to many people, I found it amazing that I could run a bunch of .exe files on my mac directly from my Windows Partition with no problems what-so-ever. My only issue with this technology at the moment, is the inability to have &#8216;browser windows&#8217; in the application run on OSX. They run on Linux apparently, but not on a Mac.</p>
<p>I really hope that .NET developers start making their applications Mono compatible, and I look forward to the browser window component being accessible on a Mac. I&#8217;ll definitely be trying my C# programs on Mono and I may even release some of them soon!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnwordsworth.com/2008/08/mono-running-net-applications-on-osxlinux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hello Mac, Bye Bye Hash Key?</title>
		<link>http://www.johnwordsworth.com/2008/01/hello-mac-bye-bye-hash-key/</link>
		<comments>http://www.johnwordsworth.com/2008/01/hello-mac-bye-bye-hash-key/#comments</comments>
		<pubDate>Mon, 14 Jan 2008 20:12:33 +0000</pubDate>
		<dc:creator>John Wordsworth</dc:creator>
				<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.johnwordsworth.com/blog/2008-01-14/hello-mac-bye-bye-hash-key/</guid>
		<description><![CDATA[My initial experiences with a MacBook and the infuriating lack of a hash key unless you know the hidden knowledge of the mac.]]></description>
			<content:encoded><![CDATA[<p>Just a couple of days ago saw the acquiring of my new Intel MacBook. It wasn&#8217;t many hours into using my new piece of hardware that I set myself back to work &#8211; some web-design and CSS work was in dire need of completion.Now, there are a few keys that have been moved around on the Mac keyboard compared to my old laptop, and it&#8217;s still not unusual for me to have a hunt around the keyboard for a button that I need. The most interesting situation came, however, when it was time to define some CSS elements requiring the Hash Key.</p>
<p>My usual reflex didn&#8217;t insert a #, so my eyes headed south. A minute passed and I scanned every key afore me. No sign of a hash &#8211; I must have missed it, so I look again. Nothing! Luckily, a friend of mine has a mac, so knows that the &#8216;intuitive&#8217; short-cut is infact <span class="Apple-style-span" style="font-weight: bold">Alt-3</span>.</p>
<p>However, had I not had that support there, I would&#8217;ve been rather aggravated. I hope this saves someone some hair-pulling at a later date!Otherwise, my experience with the MacBook has been sterling. It runs very smooth, and most interestingly &#8211; everything integrates exceptionally well &#8211; even integrating with windoze. If I click on Network Shares, the drives appear instantly, and doesn&#8217;t freeze my entire PC just to browse these shared folders. PDF&#8217;s no longer freeze my browser, and I can use Firefox just to remind me of my old laptop.</p>
<p>More to come at a later date &#8211; but my current mission is to program a Dashboard Widget and some Cocoa demos to see what Mac Development is like.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnwordsworth.com/2008/01/hello-mac-bye-bye-hash-key/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>HTC TyTn / Hermes on 3 / Three Mobile (UK)</title>
		<link>http://www.johnwordsworth.com/2007/08/htc-tytn-hermes-on-3-three-mobile-uk/</link>
		<comments>http://www.johnwordsworth.com/2007/08/htc-tytn-hermes-on-3-three-mobile-uk/#comments</comments>
		<pubDate>Fri, 10 Aug 2007 21:48:24 +0000</pubDate>
		<dc:creator>John Wordsworth</dc:creator>
				<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.johnwordsworth.com/blog/2007-08-10/htc-tytn-hermes-on-3-three-mobile-uk/</guid>
		<description><![CDATA[After purchasing a Vodafone v1605 (aka. the HTC TyTn / Hermes), I tell my story of getting my new toy to work on the 3 Mobile Network - with Planet 3 and all.]]></description>
			<content:encoded><![CDATA[<p align="left"><a href="http://www.johnwordsworth.com/blog/wp-content/uploads/2007/08/htctytn.jpg" title="HTC TyTn / Hermes"><img src="http://www.johnwordsworth.com/blog/wp-content/uploads/2007/08/htctytn.thumbnail.jpg" align="left" alt="HTC TyTn / Hermes" style="border-width: 1px; border-color: black; border-style: solid" /></a>I recently bought myself a <a href="http://en.wikipedia.org/wiki/HTC_TyTN" target="_blank" title="HTC TyTn on Wikipedia">HTC TyTn</a>, confusingly, also known as the <a href="http://en.wikipedia.org/wiki/HTC_TyTN" target="_blank" title="HTC Hermes on Wikipedia">HTC Hermes</a>, Orange M3100, O2 XDA Trion, Vodafone v1605, iMate JasJam and a whole plethora of other names. The <a href="http://www.ebay.co.uk" target="_blank" title="eBay - Online Auctions">eBay</a> auction specifically stated &#8220;<em>unlocked, but doesn&#8217;t work on Three mobile</em>.&#8221;</p>
<p>This was interesting, as the first thing I did when I got the item was stick my <a href="http://www.three.co.uk" target="_blank" title="Three Mobile">3 Mobile</a> Sim card in it to find that it worked fine. I also did a bit of net searching to find conflicting reports on fairly serious questions: Will my phone get blocked by 3? Will I be able to access Planet 3? Will I ever be able to make video calls?Well, to date, I&#8217;ve had no problems what-so-ever. No angry text messages from 3 telling me this isn&#8217;t my regular phone, no problems accessing Planet 3 to see how many minutes I&#8217;ve got left, and I must confess, I&#8217;ve not tried to make a video call yet. So, in order to aid any other people that are having these worries, this is what I&#8217;ve done;I flashed the ROM and installed the &#8216;Black Satin&#8217; version of Windows Mobile 6.0. I then downloaded the 3.cab from XDA Developers, put this on my device using Active Sync and then ran the .cab file. Now, this certainly isn&#8217;t necessary, and all of the settings worked without doing this, but I like upgrading this and having more buttons. Now, some tips for the 3 Mobile UK Owner.<strong>3 Internet Connection Settings</strong> (Settings / Connections)<br />
<table align="center" style="width: 450px">
<tr>
<td><strong>Modem:</strong></td>
<td>Cellular Line (GPRS, 3G)</td>
</tr>
<tr>
<td><strong>Access Point Name (APN):</strong></td>
<td>three.co.uk</td>
</tr>
<tr>
<td><strong>Username / Password / Domain:</strong></td>
<td>Blank</td>
</tr>
</table>
<p><strong>MMS Settings</strong> (Messaging / SMS/MMS / New Message / Message Options / Servers)<br />
<table align="center" style="width: 450px">
<tr>
<td><strong>Gateway:</strong></td>
<td>mms.three.co.uk</td>
</tr>
<tr>
<td><strong>Port:</strong></td>
<td>8799</td>
</tr>
<tr>
<td><strong>Server Address:</strong></td>
<td>http://mms.um.three.co.uk:10021/mmsc</td>
</tr>
<tr>
<td><strong>Send Limit:</strong></td>
<td>300k</td>
</tr>
<tr>
<td><strong>WAP Version:</strong></td>
<td>2.0</td>
</tr>
</table>
<p>Last but not least, if you want to access <strong>Planet 3</strong> you can simply fire up Internet Explorer and visit mobile.three.co.uk. One final warning &#8211; if you want to check if you&#8217;re on 3G or not, look at the icon at the top of the screen. I believe, if you try to use GPRS when you&#8217;re not in a 3G area (your network will be displayed as &#8220;3&#8243; for GPRS, or &#8220;UTMS 3&#8243; for the full &#8217;3G access&#8217;) then you&#8217;ll be considered to be roaming, which means you&#8217;ll be charged money, where as, if you&#8217;re in a UTMS 3 area, you&#8217;ll not be charged. However, if your network just comes up as &#8217;3&#8242;, then you can still make calls / send SMS messages on your free credit.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnwordsworth.com/2007/08/htc-tytn-hermes-on-3-three-mobile-uk/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Logical Prediction of Web 3.0</title>
		<link>http://www.johnwordsworth.com/2007/06/logical-prediction-of-web-30/</link>
		<comments>http://www.johnwordsworth.com/2007/06/logical-prediction-of-web-30/#comments</comments>
		<pubDate>Sat, 09 Jun 2007 00:03:49 +0000</pubDate>
		<dc:creator>John Wordsworth</dc:creator>
				<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.johnwordsworth.com/blog/2007-06-09/logical-prediction-of-web-30/</guid>
		<description><![CDATA[A complete stab in the dark at what could well be some of the defining features of what will one day, undoubtedly, have the mysterious name 'Web 3.0'. I thought I would extrapolate the lines that connect the 'read only web 1.0' to the features we know relate to Web 2.0.]]></description>
			<content:encoded><![CDATA[<p>A complete stab in the dark at what could well be some of the defining features of what will one day, undoubtedly, have the mysterious name &#8216;Web 3.0&#8242;. I thought I would extrapolate the lines that connect the &#8216;read only web 1.0&#8242; to the features we know relate to Web 2.0.</p>
<p><strong>Constant Streaming Data:</strong> In the beginning, you would request a page once, and read it. With Web 2.0, you often request a page for a section / specific use application, and use it. Thus, I suggest that with Web 3.0, you will visit the homepage of a site that will provide the majority of the functionality of the site without a page refresh &#8211; the site will change to suit your needs, like a real world application.</p>
<p><strong>Syndication and Aggregation of Sites and Functionality:</strong> Where Web 2.0 has seen the syndication of data across multiple websites, I propose that Web 3.0 might present the possibility to syndicate web applications / entire pages or sites or even just specific functions of a website. As bandwidth becomes cheaper, it will be easier to syndicate applications from a single source than to have multiple copies dotted around the web.</p>
<p><strong>Mobile Web to reach &#8216;Web 2.5&#8242;:</strong> In the current day, the majority of websites based at Mobile Phones aren&#8217;t quite Web 2.0, due to the limited capacity of features and memory available to mobile devices. As they improve however, they will take a very important role in the way the web moves forwards. People will expect to access their favourite sites as easily from their mobile phone as they can from their PC. Non-Geeks will blog from their phone and update data whilst walking to work.</p>
<p><strong>Complete Microformat Integration with Real Devices:</strong> No longer will some sites support specific microformats that a small selection of specially made tools can make use of, but microformatted data will be exchanged directly between websites keeping all of your often visited sites synchronised, as well as your mobile phone, and even your microwave and your fridge (with a shopping list and todo list etc).</p>
<p><strong>Further Abstracted Design:</strong> CSS will be cleaner and cross-browser incompatibilities will (hopefully) be a thing of the past. New XHTML objects and new layout languages may come into use to allow for advanced features to be built directly into the web (auto-complete combo boxes, hover-over boxes, trees, expanding and movable divs etc). Designers will have to worry even less about how things will work, and programmers will have to worry even more about the complex points of programming.</p>
<p><strong>Programmable Open Source Platform:</strong> The web will become a place where you cannot only just add data to wiki&#8217;s, but program how they function and add applications to other websites. Simple drag and drop programming models will even allow for standard web users to add functionality to their own pages/blogs/other sites without danger of breaking the server or disastrous consequences. People will even login to their own customized (web-based, or web-attached) applications to access their files online, because they&#8217;ve added functionality to their applications themselves.</p>
<p>Just my logical prediction. Some of this will undoubtedly be wrong, but I look forward to matching it up in a few years time.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnwordsworth.com/2007/06/logical-prediction-of-web-30/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

