<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">

    <title type="text">M Cubed Blog</title>
    <subtitle type="text">M Cubed Blog:</subtitle>
    <link rel="alternate" type="text/html" href="http://www.mcubedsw.com/blog/index.php/site/comments/" />
    
    <updated>2011-11-25T13:43:39Z</updated>
    <rights>Copyright (c) 2011, M Cubed</rights>
    <generator uri="http://www.pmachine.com/" version="1.6.8">ExpressionEngine</generator>
    <id>tag:mcubedsw.com,2011:11:25</id>


    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/mdiced" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="mdiced" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
      <title>Six</title>
      <link rel="alternate" type="text/html" href="http://www.mcubedsw.com/blog/index.php/site/six/" />
      <id>tag:mcubedsw.com,2011:blog/index.php/site/comments/1.112</id>
      <published>2011-11-25T13:42:29Z</published>
      <updated>2011-11-25T13:43:39Z</updated>
      <author>
            <name>M Cubed</name>
            <email>pilky@mcubedsw.com</email>
                  </author>

      <category term="General" scheme="http://www.mcubedsw.com/blog/index.php/site/C/" label="General" />
      <content type="html"><![CDATA[
        <p>The last year seems to have zoomed by. It only just occurred to me a few days ago that it is going to be 6 years since I started M Cubed. That makes it a quarter of my life. So what exactly did I do with myself the past year and what do I plan to do with M Cubed's 6th year?</p>

<br/>
<h3>Things Went Terribly…</h3>

<p>The past few months I've constantly had doubts about M Cubed and myself as a software developer. I've been feeling like I've achieved nothing the past few years since I went full time with M Cubed. Sales that were initially heading in a positive direction have somewhat stagnated. They're enough for me to live off, but only because I moved back with my parents after university.</p>

<p>I've felt like progress has been slow. This year has been dominated by Lighthouse Keeper 2. It has taken 9 months to create, but probably should have been more like 6 or 7. I wanted to be so much further along with various applications and be getting releases out more frequently. But that hasn't happened.</p>

<p>And on top of all that has been the crisis of confidence in myself as a software developer. I've been programming for 8 years now, but recently I've had many moments where I feel like I know absolutely nothing about anything to do with software development. I've felt like I don't know how to design software, to write good code, to even solve trivial problems. I've also felt like I work incredibly slowly, at least compared to the speed of some other developers I know.</p>
<br/>
<h3>…Or So I Thought</h3>

<p>Given all this context, when I looked back at last year's post I chucked when I saw what I said I'd like to achieve. I wanted to get Code Collector Pro 1.5, Storyboards 1.1 and Lighthouse Keeper 1.2 out. "What a ridiculous and naive goal," I thought, "I haven't done any of that". After a bit more thought though, it dawned on me that I did actually do all of that (well, almost). Code Collector Pro 1.5 and Storyboards 1.1 were both released this year. Lighthouse Keeper 1.2 ended up morphing into 2.0 and will hopefully be released in early december.</p>

<p>Whenever I've looked back at the past 2 years I've focused so much on what I haven't done and where I'm not. It was only the past few days, when I've been wondering what to write for this year's post, that I've thought about what I have actually achieved.</p>

<p>First and foremost, I'm writing software full time and am able to make some sort of living off that. Now granted it's a somewhat cheap living, without my own place or any exotic holidays, but I can afford the occasional game or gadget to keep me happy. But the thing is, many people never even get to this stage, so I have a lot to be thankful for. I may have technically been doing this 6 years, but 4 of those were part time, as more of a hobby than anything. In reality I'm still getting started.</p>

<p>Lighthouse Keeper 2 is also a great example of how much I've improved the past 12-18 months. It is by no means perfect (is any software?) but it is by far the best piece of software I've written to date. It is powerful, it is well designed, it looks great. On top of this the code is pretty good too. I spent a lot of time figuring out how things should work early on, which led to slow progress. But in the latter stages of development I was constantly surprising myself with how easy I was finding it to add features. I'd add something and it would just work with everything else. I'm incredibly proud of myself for that.</p>
<br/>
<h3>Learning The Tools Of The Trade</h3>

<p>I've also learned a LOT this past year. I've gone much deeper into how my tools work. I've pushed myself to learn more and more about Xcode, which has not only helped me develop software more easily, but also let me write my reviews whenever each new version comes out. I know more about how to effectively debug my software which has helped find bugs much faster.</p>

<p>Testing has always been a thorn in my side. I've always done it manually. There have been a few bits of code I've automated the testing for, but those tests were rarely run. I've always put off automating it all, partly due to laziness, partly due to "more urgent" matters, partly due to Xcode 3 being rather crap in this regard. Mostly though it was because I found it such a pain.</p>

<p>So the past few years I've been finding ways to reduce the pain to a point where I write more tests. Improving the quality of my code has helped a lot, but I've also learned the value of pragmatism. I found a lot of stuff I needed for testing I didn't need for shipping code and so it was just make my code messier and harder to read. So I found ways to allow a class to be easily testable while maintaining clean, elegant code for shipping (while also having the benefit of points of extensibility down the line if I ever need it). And while its benefits may be questionable, tracking my test coverage has helped spur me on by giving me some measurable sign of progress.</p>

<p>I've also finally set up a continuous integration system. I've dabbled with it before but given my aforementioned aversion to writing automated tests I didn't see the use. Now granted the majority of errors the CI system has caught so far have been build issues that only affected itself, but the few times it has caught a failed test has helped. And being tied into my source control system means that it always runs.</p>

<p>Another area I've looked to improve is documentation. I've always been fairly reasonable about commenting my code, but I'm trying to take this a step further, but extensively commenting everything, while also writing higher level documentation to help me see how the various components fit together.</p>

<p>And I've become much more proficient at scripting, letting me automate various other parts of my system or extend my tools with additional functionality.</p>

<br/>
<h3>For the Future</h3>

<p>So what will the future bring? Well the immediate future is to get Lighthouse Keeper 2 out. I'll also be spending all of December on those jobs I've kept putting off. The M Cubed website needs a complete re-write, which is also a good opportunity to finally sit down and properly learn Rails. I've got a HUGE amount of code I'd like to finally open source, including many internal frameworks and utility apps I use. I also started work on improving the Appledoc documentation generator, as well as writing a UI testing system for Mac apps, so I'd like to get those finished. I've always felt guilty working on such projects instead of apps, even though I know they'll help me long term, so I'm glad to just dedicate a month to them.</p>

<p>For 2012 I want to get major new versions of Syllabus, Storyboards and CCP out. These will, like Lighthouse Keeper 2, allow me to prepare for the future. They will finally allow me to reach the fabled land of "smaller, more frequent releases" that I talked about last year by cleaning up the source based and structuring it in a way that lets me add features and fix bugs faster. Hopefully I'll also be able to get some of these smaller releases out as well, but I suspect that a lot of my time will be taken up by these 3 big releases.</p>

<p>I also want to continue with my learning. I'd like to explore further into Instruments, which is seen as a mystical land by many, as well as give JetBrains' AppCode a try for a month (and write a review for it like my Xcode reviews). I've also reached the point where I'm confident in doing a lot of design work by myself, but I don't have enough knowledge of the theory behind it, so I'll be spending time doing research there.</p>

<p>A friend has convinced me that I should try to adopt agile development practices. So in 2012 I'm planning to take a proper stab at learning them and see what can apply to my situation. One of my big problems at the moment is a lack of structure in how I develop software, so hopefully a bit more structure will help me get releases out quicker, while also making sure I don't forget many of the ancillary things.</p>

<p>And finally, I'm going to commit to doing some contracting over the next year. I'm hoping to dedicate 10-15 hours a week to it, so it is a significant part of my week without taking it over. Part of the reason for this is simply to get some more money coming in so I can invest it in improving my apps further. But I've also had little experience with working with others the past 2 years. I haven't worked in a team, nor written software where the requirements weren't set by myself since I left university. I've been getting very rusty in this regard and it has been impacting my apps somewhat.</p>

<br/>

<p>That's a rather long and detailed description of my goals for the next year compared to what I've written in previous years. But the thing I've realised most the past few days is that I can't just measure myself by how well I'm doing financially or how many software releases I have. There are other areas such as what I learn, that are just as important and where I've made a lot of progress. Whether I achieve all I've set out to do, we'll see in 12 months time. All I know is that for most of 2011 I've been in a slump, with little confidence in myself and no idea what the future will hold. Writing this post though, has given me new life and a similar eagerness to what I felt when I first started in this industry. Here's to year 7 of M Cubed Software!</p> 
      ]]></content>
    </entry>

    <entry>
      <title>Lighthouse Keeper Connection Issues</title>
      <link rel="alternate" type="text/html" href="http://www.mcubedsw.com/blog/index.php/site/lighthouse_keeper_connection_issues/" />
      <id>tag:mcubedsw.com,2011:blog/index.php/site/comments/1.111</id>
      <published>2011-04-25T14:37:54Z</published>
      <updated>2011-04-25T16:57:02Z</updated>
      <author>
            <name>M Cubed</name>
            <email>pilky@mcubedsw.com</email>
                  </author>

      <category term="Lighthouse Keeper" scheme="http://www.mcubedsw.com/blog/index.php/site/C/" label="Lighthouse Keeper" />
      <content type="html"><![CDATA[
        <p><b>Update: It seems the folks over at ENTP have fixed the SSL certificate, you should be ok to revert your settings.</b></p>

<p>You may be noticing connection issues with Lighthouse Keeper today, with it not downloading updates or letting you edit anything. It seems Lighthouse's SSL certificate has expired. This will likely be fixed some time soon, but in the mean time you probably want to keep using Lighthouse Keeper. Here's a step-by-step guide to getting around the issue.</p>

<p><b>1.</b> Visit your Lighthouse account in the browser.</p>

<p><b>2.</b> You should be presented with a dialogue like the one below. Click the "Show Certificate" button</p>

<div align="center" style="padding:10px 0px 20px 0px"><img src="http://www.mcubedsw.com/images/blog/lhkerror-certificate.png"/></div>

<p><b>3.</b> In the bottom panel there should be a heading called "Trust" with a disclosure triangle next to it. Click on this</p>

<p><b>4.</b> There will be 3 pop up buttons appear. Change the one labelled "Secure Sockets Layer (SSL)" to "Always Trust".</p>

<div align="center" style="padding:10px 0px 20px 0px"><img src="http://www.mcubedsw.com/images/blog/lhkerror-trust.png"/></div>

<p><b>5.</b> Click continue. When prompted, enter your keychain password.</p>

<p>You should now be able to use Lighthouse Keeper without any issues as these changes work across the whole of your OS, not just your browser. You may want to change this value back after Lighthouse have fixed it. In order to do that, open Keychain Access, click on the Certificates category on the left, search for a certificate called *.lighthouseapp.com (it should have + next to its icon). Once found click the i button and perform steps 3 and 4 in the window that pops up, except change the pop up back to "no value specified". Close the window, enter your keychain password and everything should be back to normal.</p> 
      ]]></content>
    </entry>

    <entry>
      <title>Code Collector Pro 1.5</title>
      <link rel="alternate" type="text/html" href="http://www.mcubedsw.com/blog/index.php/site/code_collector_pro_1.5/" />
      <id>tag:mcubedsw.com,2011:blog/index.php/site/comments/1.110</id>
      <published>2011-03-22T11:31:55Z</published>
      <updated>2011-03-22T11:32:25Z</updated>
      <author>
            <name>M Cubed</name>
            <email>pilky@mcubedsw.com</email>
                  </author>

      <category term="Code Collector" scheme="http://www.mcubedsw.com/blog/index.php/site/C1/" label="Code Collector" />
      <content type="html"><![CDATA[
        <p>It has taken a while (I'd hoped to have this out last year), but Code Collector Pro 1.5 is now out. The main focus of 1.5 has been improving existing features rather than adding new ones. The two big improvements are to syntax colouring and to import/export.</p>

<p>The syntax colouring was actually added in CCP 1.4.4 as a hidden feature, but it is now enabled by default. You can find out about the improvements <a href="http://www.mcubedsw.com/blog/index.php/site/comments/code_collector_pro_1.4.4_and_its_dirty_little_secret/">here</a>.</p>

<p>The import and export functionality is a massive improvement. Previously you could import or export snippets or export your library as plain text. You can still do these but there are some major improvements. For starters, you can now import your library from Coda, Snippet, Snippets or TextExpander if you have been using one of those apps. You can also export your library to XML, which unlike the plain text format can be re-imported, making it highly useful for backups.</p>

<div align="center"><img src="http://www.mcubedsw.com/images2010/ccp/whatsnew-import.png"/></div>
<br/>
<h3>Universal Snippet Format</h3>

<p>When importing and exporting snippets, Code Collector Pro 1.5 uses a new format. It has the same .snippet extension as previous versions of Code Collector Pro, but it is designed to be a universal format for transferring snippets. The format has been developed with the developers of both Snippets and CodeBox. Code Collector Pro is the first to implement the format, but hopefully over the coming months you'll also see support in both Snippets and CodeBox.</p>

<p>We really want to push this as a universal format, and to help with that I've published the source for the parsing framework <a href="https://github.com/pilky/SNSnippetArchiving">to Github</a> so that others can easily add it to their Cocoa apps. The format is simply XML so could also potentially be used by web APIs for sending snippet data. I'll be posting full information about the spec online as and when I find the time.</p>

<br/>
<h3>Extra Goodies</h3>

<p>There are also some extra improvements that have been added. The first is that the line number size now grows and shrinks with the text size. It is a minor improvement, but one that has been requested by quite a few people.</p>

<p>The other improvement is one that has been asked for by a lot of people, but it isn't recommended so is a bit hidden. You can now change the location CCP looks for your library file. By using the following command in the terminal you can change it to anywhere on your system &#40;change the path at the end as appropriate&#41;:

<pre>defaults write com.mcubedsw.codecollectorpro M3DatabasePath -string /path/to/database.sql</pre>

<p>CCP won't transfer the library file to the new location, and only loads the path on launch, so if you want to move an existing library I recommend quitting CCP, moving the file using the finder, running the above command and then launching CCP again.</p>
<br/>
<h3>App Store Availability</h3>

<p>Lastly, Code Collector Pro 1.5 will be the first M Cubed app in the App Store. It hasn't yet been submitted as I wanted to get 1.5 finalised out to existing customers before focusing on readying it for the App Store. I'm hoping I can get it submitted sometime next week, after which it is in Apple's hands as to when it will be approved.</p> 
      ]]></content>
    </entry>

    <entry>
      <title>5 years, 5 apps</title>
      <link rel="alternate" type="text/html" href="http://www.mcubedsw.com/blog/index.php/site/5_years_5_apps/" />
      <id>tag:mcubedsw.com,2010:blog/index.php/site/comments/1.109</id>
      <published>2010-11-26T16:55:05Z</published>
      <updated>2010-11-26T16:55:06Z</updated>
      <author>
            <name>M Cubed</name>
            <email>pilky@mcubedsw.com</email>
                  </author>

      <category term="General" scheme="http://www.mcubedsw.com/blog/index.php/site/C/" label="General" />
      <content type="html"><![CDATA[
        <p>It's that time of year again to write the M Cubed Birthday Year-In-Review Extravaganza™ post (albeit one day late). So what happen with M Cubed over the past 12 months and what would I like to have happen over the next 12 months</p>
<br/>
<h3>The Barren Spell</h3>
<p>I had hoped that this year would have been the most productive in M Cubed's history. Sadly barring this past week it has ended up the worst. Prior to this week there had just been two major updates: Minim 2.0 and Code Collector Pro 1.4. But those both happened prior to April. From April to November there wasn't a single major release of any product and it is all down to the iPad.</p>

<p>After releasing Code Collector Pro 1.4 I started work on Lighthouse Keeper 1.2. Sadly this work was interrupted by the release of the iPad. I had a plan to write an iPad app and set to work designing it. It was going to be a whiteboarding app and it was going to be great. Except it didn't really work well as an idea, so I then moved onto a notebook app. I designed it and even started coding, but it was a pain to do, so I redesigned it. And I started coding this 3rd design, but again it was awkward. So then I focused on an app that was more a collection of lose papers.</p>

<p>But again the idea didn't go too far. Then I finally had an epiphany. The idea for the iPad app had initially come from that of an app I'd be planning for the Mac. It would be a sort of interactive storyboarding app, letting you storyboard almost anything. So I decided to create a storyboarding app for iPad.</p>

<p>Unfortunately by now it was July so I'd wasted over 3 months on failed attempts. So I set to work straight away, planning, designing and coding. Features were planned and many cut all in the effort to make 1.0 as soon as possible. Finally on Monday, nearly 8 months after I decided to make an iPad app, Storyboards was released.</p>

<p>Sales have been going well, the best of any new M Cubed app. Sadly the feedback hasn't been quite as good. The reviews largely focus on how little it seems to do for the price. And to be frank I do agree with them, but I had to cut features out to release on time, features that will, over the coming 12-18 months make their way back in.</p>
<br/>

<h3>Indecision</h3>

<p>The big issue this year has been indecision and bad decisions. I've changed my mind too much and lost a lot of time due to it. About a month prior to the release of Storyboards I realised that I should make things work differently to allow for more flexibility in the future, and I cam very close to re-doing large parts of the app.</p>

<p>Thankfully, I've learned my lesson. I decided that 1.0 would ship as is and I can gradually change things over future versions. Sure it would be underpowered and not as flexible a tool as I wanted, but it would be released, earning money and generating feedback. And I could start work on other stuff.</p>
<br/>

<h3>Acquisition</h3>
<p>Not too long ago I saw a tweet from a friend on Twitter. He was looking to sell his apps off as he didn't have time for them as well as other things in his life. I jumped at the chance to gain another app, especially one with lots of future potential and so we started talking. Yesterday the announcement was made public and Syllabus became M Cubed app number 5 (technically not the 5th we've ever had but the 5th app we currently sell).</p>
<br/>

<h3>Scaling Back</h3>
<p>There has also been some scaling back this year at M Cubed. Fabio left for other things taking the employee count down to "just me" again. As such M Cubed has also stopped offering any design services and I'm focusing purely on writing apps.</p>
<br/>

<h3>Future Plans</h3>
<p>So what are the future plans? Well for the next 6 months I'd like to try and get Lighthouse Keeper 1.2, Storyboards 1.1 and Code Collector Pro 1.5 out. Lighthouse Keeper 1.2 will be the last large update I'll do for a long while. All future updates will have at most one big new feature or two medium new features but no more. "Smaller, more frequent releases" is the mantra for 2011. Hopefully I can stick to it, but we'll have to see this time next year when I'm writing a post for M Cubed's 6th birthday.</p> 
      ]]></content>
    </entry>

    <entry>
      <title>Storyboards: Coming Soon to an iPad Near You</title>
      <link rel="alternate" type="text/html" href="http://www.mcubedsw.com/blog/index.php/site/storyboards_coming_soon_to_an_ipad_near_you/" />
      <id>tag:mcubedsw.com,2010:blog/index.php/site/comments/1.108</id>
      <published>2010-10-28T11:03:08Z</published>
      <updated>2010-11-26T17:23:09Z</updated>
      <author>
            <name>M Cubed</name>
            <email>pilky@mcubedsw.com</email>
                  </author>

      <category term="M Cubed News" scheme="http://www.mcubedsw.com/blog/index.php/site/C3/" label="M Cubed News" />
      <content type="html"><![CDATA[
        <p>Today I'm happy to reveal the first details of M Cubed's next application, and our first iOS app: Storyboards. As you can probably guess, this is an app for storyboarding ideas. You will be able to draw boards, add information such as dialogue or a description and then play back sequences to get a feel for how they flow.</p>

<p>I'll be giving more details over the coming weeks building up to the release, but until then visit the new <a href="http://www.mcubedsw.com/software/storyboards">Storyboards page</a> to watch the teaser video and sign up for updates</p> 
      ]]></content>
    </entry>

    <entry>
      <title>Code Collector Pro 1.4.4 (And Its Dirty Little Secret)</title>
      <link rel="alternate" type="text/html" href="http://www.mcubedsw.com/blog/index.php/site/code_collector_pro_1.4.4_and_its_dirty_little_secret/" />
      <id>tag:mcubedsw.com,2010:blog/index.php/site/comments/1.107</id>
      <published>2010-09-03T14:11:40Z</published>
      <updated>2010-09-03T14:11:40Z</updated>
      <author>
            <name>M Cubed</name>
            <email>pilky@mcubedsw.com</email>
                  </author>

      <content type="html"><![CDATA[
        <p>Code Collector Pro 1.4.4 is now out and features a few improvements and bug fixes. The big public improvements are that you can now drag files to groups to create a snippet in that group and drag a snippet to the finder to create a file on disk.</p>

<p>The biggest improvement though isn't yet turned on by default. Ever since CCP 1.0, the syntax highlighting has been something I've been disappointed with. It was slow, it was buggy and it was inaccurate. It has also been the number one source of complaints about CCP. So obviously it needed to be re-written, which is what I've been working on recently.</p>

<p>The plan was to get improved syntax highlighting into CCP 1.5, and the plan still is for it to be public and turned on by default in 1.5. However, it could benefit people now, even in its relatively early state.</p>
<br/>
<h3>Turning On The New Engine</h3>
<p>The new syntax highlighting engine is off by default, as at the moment it is classed as a beta feature (meaning it could be buggy and could crash the app). It also only works if you are running on Mac OS X 10.6, so if you enable it on 10.5 you will see no difference as it will still use the old engine. To turn it on you need to drop down to terminal and enter the following:</p>

<pre style="width:600px">defaults write com.mcubedsw.codecollectorpro M3EnableNewSyntaxHighlighting -bool YES</pre>

<p>If you then restart Code Collector Pro it should start using the new engine to colour some of your snippets.</p>

<p>Why only some though? Well the reason is performance. While the new engine is far more accurate and less buggy, it has not had one bit of performance optimisation done on it. As such is is limited in two ways. The first is that it doesn't render anything that contains a line longer than 500 characters. The main cause of this is condensed jQuery. This will be fixed before 1.5 but for now it just falls back to the old engine.</p>

<p>The second is that it doesn't render anything that is longer than 120 lines. This is just an arbitrary number I've picked based on some timing tests. The good news is though that you can customise this number. While the line length issue can cause CCP's memory usage to balloon rapidly and possibly crash, the number of lines issue is simply one that may cause the app to hang for several seconds while it processes. If you don't mind this and want to try it on bigger snippets then you can modify it from terminal like so (this example sets the limit to 200 lines:</p>

<pre style="width:600px">defaults write com.mcubedsw.codecollectorpro M3NewSyntaxHighlightingLineCountLimit 
-int 200</pre>

<br/>
<h3>Extra Colours</h3>
<p>Along with the new engine there are some extra options for colouring. These don't do anything in the old engine, but they allow you to set colours for pre-processor macros, variables and attributes in your code.</p>

<br/>
<h3>Examples</h3>
<p>Below are before and after shots of some snippets in Ruby, Actionscript, HTML and Objective-C to show you the sorts of improvements in the new engine.</p>
<br/>

<h4>Ruby</h4>
<p>As you can see, Ruby code is massively improved, with all the strings and keywords being correctly found and comments being coloured in.</p>
<div align="center">
<img src="http://www.mcubedsw.com/images/blog/oldruby.png"/>
<img src="http://www.mcubedsw.com/images/blog/newruby.png"/>
</div>
<br style="clear:both"/><br/><br/>


<h4>Objective-C</h4>
<img src="http://www.mcubedsw.com/images/blog/oldobjc.png" style="float:right; margin-bottom:20px"/>
<img src="http://www.mcubedsw.com/images/blog/newobjc.png"style="float:right"/>
<p>The Objective-C snippet gets the comment properly coloured, the correct keywords highlighted, variables and classes highlighted and the preprocessors highlighted</p>
<br style="clear:both"/><br/><br/>


<h4>HTML</h4>
<img src="http://www.mcubedsw.com/images/blog/oldhtml.png"style="float:right; margin-bottom:20px"/>
<img src="http://www.mcubedsw.com/images/blog/newhtml.png"style="float:right"/>
<p>Tags are properly highlighted now, and attribute names and values can also be coloured</p>
<br style="clear:both"/><br/><br/>


<h4>ActionScript</h4>
<p>ActionScript has variables and symbols correctly coloured in and fewer incorrect highlights (see the resizeHandler argument)
<div align="center">
<img src="http://www.mcubedsw.com/images/blog/oldas.png"/>
<img src="http://www.mcubedsw.com/images/blog/newas.png"/>
</div>

<br/><br/>
<h3>Feedback</h3>
<p>As this is still a feature under development, I'm eager to hear any feedback and any bugs you find. It isn't yet perfect so if you find a snippet that it doesn't colour properly then send an email to <a href="support@mcubedsw.com">support@mcubedsw.com</a> and include the snippet, so I can try and fix it</p> 
      ]]></content>
    </entry>

    <entry>
      <title>Extended 50% Educational Discount</title>
      <link rel="alternate" type="text/html" href="http://www.mcubedsw.com/blog/index.php/site/extended_50_educational_discount/" />
      <id>tag:mcubedsw.com,2010:blog/index.php/site/comments/1.106</id>
      <published>2010-09-01T12:14:26Z</published>
      <updated>2010-09-01T12:14:26Z</updated>
      <author>
            <name>M Cubed</name>
            <email>pilky@mcubedsw.com</email>
                  </author>

      <category term="M Cubed News" scheme="http://www.mcubedsw.com/blog/index.php/site/C3/" label="M Cubed News" />
      <content type="html"><![CDATA[
        <p>I'm happy to announce that the increased educational discount of up to 50% off our apps that has been running over the past few weeks will continue until the end of September. If you're a student or employee at an educational institution then visit our <a href="http://www.mcubedsw.com/store/edu">education store</a> to get a large discount on all of our apps.</p> 
      ]]></content>
    </entry>

    <entry>
      <title>New Objective-C Features [UPDATEDx3]</title>
      <link rel="alternate" type="text/html" href="http://www.mcubedsw.com/blog/index.php/site/new_objective-c_features/" />
      <id>tag:mcubedsw.com,2010:blog/index.php/site/comments/1.105</id>
      <published>2010-06-25T19:54:35Z</published>
      <updated>2011-01-18T14:14:36Z</updated>
      <author>
            <name>M Cubed</name>
            <email>pilky@mcubedsw.com</email>
                  </author>

      <category term="Coding" scheme="http://www.mcubedsw.com/blog/index.php/site/C2/" label="Coding" />
      <content type="html"><![CDATA[
        <p>Prior to Apple acquiring NeXT, Objective-C had had relatively little added to it since it became a fully fledge language rather than simply a C preprocessor back in the 80s. About the only thing added for many years after Apple acquired NeXT was the @try…@catch…@finally exception syntax.</p>

<p>Then in 2007 Apple released Leopard and with it Objective-C 2.0 and the modern runtime. This added features such as properties, fast enumeration, class extensions and garbage collection and improved areas such as protocols, while making the runtime far more flexible and less fragile to change. Last year with Snow Leopard, Apple added blocks and associative storage to the language in what can sort of be thought of as Objective-C 2.1.</p>

<p>At WWDC Apple announced a few more features, which I personally think of as Objective-C 2.2. These are "@synthesize by default" and "declare ivars in class extensions". These are features that I have wanted for quite a while and I am sure a lot of other Objective-C developers have wanted. So what are they and how do you get them?</p>

<br/>
<h3>Getting the Features</h3>

<p>To get them there are two requirements:</p>
<ul>
 <li>Your app must use the modern runtime (so no 32 bit Mac apps)</li>
 <li>You have to use LLVM 1.5 or higher as your compiler</li>
</ul>

<p>If you fulfil those requirements then you're almost able to use them. All that is left to do is add these two flags to your "Other C Flags" build setting:</p>

<ul>
 <li>-Xclang</li>
 <li>-fobjc-nonfragile-abi2</li>
</ul>

<p>So now we're all set up, what the hell are these features?</p>

<br/>
<h3>@synthesize by Default</h3>

<p><b>NB: This feature is no longer available and so should not be used. It may re-appear at some point but in the mean time we sadly have to write our @synthesize statements. I've left the section in for reference if/when it comes back</b></p>

<p>With the addition of properties, Apple was able to remove a lot of boilerplate code from our classes. If you are using the legacy runtime then you are able to write code like this:</p>

<pre style="width:600px">
==========MyClass.h==========

@interface MyClass &#123;
    NSString *foo;
&#125;

@property (copy) NSString *foo;

@end



==========MyClass.m==========

@implementation MyClass

@synthesize foo;

@end
</pre>

<p>It is a lot cleaner than what you had to write pre Obj-C 2.0, but it still has a lot of stuff to write. If you are using the modern runtime (ie are writing an iOS or 64 bit only Mac app) then you can get rid of the instance variable:</p>

<pre style="width:600px">
==========MyClass.h==========

@interface MyClass &#123;&#125;

@property (copy) NSString *foo;

@end



==========MyClass.m==========

@implementation MyClass

@synthesize foo;

@end
</pre>

<p>That's a bit cleaner, we're only having to sort out our property in two places rather than three, but it's still one too many. 95% of the time, you just want to synthesise the methods and instance variable and so the vast majority of property code in your implementation is the same. Well as you can probably guess, "@synthesize by default" means that this is done for you by the compiler by default. If you want to override it with an @dynamic statement or link it to a different instance variable you can, but for the rest of the time you can reduce your code to this:</p>

<pre style="width:600px">
==========MyClass.h==========

@interface MyClass &#123;&#125;

@property (copy) NSString *foo;

@end



==========MyClass.m==========

@implementation MyClass

@end
</pre>

<p>There is one slight gotcha with this. <strike>Due to what seems to be a compiler bug,</strike> you will get an error if you try to directly access the synthesised instance variable. Unfortunately the only ways to fix this are to either add @synthesize, add the instance variable or only access it via the property methods.</p>

<p><b>[Update]</b> It seems that this isn't a bug but is instead expected behaviour. The @synthesize methods are generated at the end of the class if you don't specify them explicitly, as the compiler can't tell if the properties need to be default synthesised until it has got to the end of the implementation.</p>

<p><b>[Update 2]</b> And now it seems the LLVM/Clang team are going to try and work around this and get it working as you would expect. Three cheers for the LLVM/Clang team!</p> 

<br/>
<h3>Declare Instance Variables in Class Extensions &amp; Implementations</h3>
<p>So, we have got rid of the instance variables for our properties, but these are public anyway, it's not that big a deal if developers can see them in the header. However, what is left are the private instance variables, the ones only used internally in a class. We can hide methods we don't want as our public interface in our implementation file, but not our instance variables. Instead we end up with this:</p>

<pre style="width:600px">
==========MyClass.h==========

@interface MyClass &#123;
    id internal1;
    id internal2;
&#125;

@end



==========MyClass.m==========

@interface MyClass ()

- (void)internalMethod;

@end


@implementation MyClass

- (void)internalMethod &#123;
    NSLog(@"%@ %@", internal1, internal2);
&#125;

@end
</pre>

<p>Thanks to Objective-C 2.0 and class extensions we can put our internal method declaration into our .m file and also have the compiler check that it is implemented and warn us if it isn't (unlike if we added a simple category). What we haven't been able to do is do the same for our instance variables. Well we can now, so our code can now look like this:</p>

<pre style="width:600px">
==========MyClass.h==========

@interface MyClass
@end


==========MyClass.m==========

@interface MyClass () &#123;
 id internal1;
 id internal2;
&#125;

- (void)internalMethod;

@end


@implementation MyClass

- (void)internalMethod &#123;
 NSLog(@"%@ %@", internal1, internal2);
&#125;

@end
</pre>

<p>Our internal instance variables really are internal now, which makes the header effectively become purely our public interface. And if you are feeling really crazy, you can have multiple class extensions and maybe just put them in the @implementation:</p>

<pre style="width:600px">
==========MyClass.h==========

@interface MyClass
@end


==========MyClass.m==========

@interface MyClass () &#123;
 id internal1;
&#125;

- (void)internalMethod;

@end


@interface MyClass () &#123;
 id internal2;
&#125;
@end


@implementation MyClass {
    id internal3;
}

- (void)internalMethod &#123;
 NSLog(@"%@ %@", internal1, internal2, internal3);
&#125;

@end
</pre>

<br/><br/><br/>
<p>These may only seem like small enhancements, but they help you reduce the code you need to write and make that which you do much neater. It is little enhancements like this that keep trickling out that makes the life of an Objective-C developer that much easier.</p> 
      ]]></content>
    </entry>

    <entry>
      <title>The End of the Tinkering Geek (aka Closed is Good)</title>
      <link rel="alternate" type="text/html" href="http://www.mcubedsw.com/blog/index.php/site/the_end_of_the_tinkering_geek_aka_closed_is_good/" />
      <id>tag:mcubedsw.com,2010:blog/index.php/site/comments/1.104</id>
      <published>2010-04-02T18:07:09Z</published>
      <updated>2010-06-26T18:26:10Z</updated>
      <author>
            <name>M Cubed</name>
            <email>pilky@mcubedsw.com</email>
                  </author>

      <category term="General" scheme="http://www.mcubedsw.com/blog/index.php/site/C/" label="General" />
      <content type="html"><![CDATA[
        <p>There has long been a grip on digital technology, so tight that it has choked much of it. It is the grip of the tinkering geek. Slowly though, this grip is being loosened and the tinkering geek is becoming less and less relevant to technology and to society. And I say good riddance.</p>

<p>The tinkering geek, by definition loves to tinker. They want to be able to open something up, hack it together, use it for something for which it wasn't originally intended. The tinkering geek wants to run Linux on a toaster or use their iPhone as a remote for everything in their house. The tinkering geek is also who designs and makes a lot of digital products.</p>

<p>Now you may think that these people are the sort of people you want working on designing and building this stuff. They know the subject, they have interesting ideas, they know what they want. The reality is these are the worst people to design anything. For all that they do know, they don't know the most important thing: what does a regular person want?</p>

<br/>
<h3>Closed is good</h3>

<p>We are brainwashed from childhood that open is good, choice is good, freedom is good. And yes, to a degree all of those are good. But too much openness leads to unhappiness, too much choice leads to confusion and too much freedom leads to anarchy. There's a reason I don't have the freedom to walk down the street killing everyone I see.</p>

<p>Closed isn't inherently bad. Design by committee is open, design by a single person is closed. I can guarantee that the design by committee will produce a worse product. Open is good in some places and bad in others. Lets take software for example. Tell me a good piece of open source software that is a backend product eg server software, framework etc. There are 100s out there that are best in their class. Now tell me a good piece of open source software aimed at regular people. Not all that many.</p>

<p>Closed also leads to things that open can't. Apple's ecosystems are often considered closed. OS X only runs on Macs, iPhone OS only runs on iPhone, iPod touch and iPad. Compare this to Windows or Android which runs across 1000s of hardware configurations. Well, if we do compare then we'll see that Apple's ecosystems are generally more stable because they have more control.</p>

<p>One example of a closed ecosystem in our products is Code Collector Pro and codecollector.net. By controlling the whole stack we will be able to implement stuff faster than competitors and even add some things that others aren't able to do at all. If we chose to be completely open and let it work with everything, it is more work for us, more code (increasing the chance of bugs) and doesn't really do anything quite as well.</p>

<p>Now I'm not saying everything in the world should be completely closed. I believe that some things need to be open, but most of these are things for people creating products to take advantage of, not for users to care about. A user doesn't care if a file format is an open standard. What they do care about is "can I save this at work and open it at home" and "will I be able to open it in a few years time".</p>

<br/>
<h3>Choice is bad</h3>

<p>There was a great TED talk a few years ago on the <a href="http://www.ted.com/talks/lang/eng/barry_schwartz_on_the_paradox_of_choice.html">"Paradox of choice"</a> by a psychologist called Barry Schwartz. You should really watch the full video, but in a nutshell he points out that choice makes people unhappy and reduces your freedom. You don't want to spend choosing, you want to spend time doing. The best way to give users what they want is to have a few distinct choices rather than a large range of slightly different choices.</p>

<p>Apple is a prime example of this. Say I want a computer, here is the general thought process:</p>

<ul>
 <li>Do I want a desktop or laptop? <strong>Laptop</strong></li>
 <li>How big a screen do I want? <strong>13"</strong></li>
 <li>Do I care most about power, price or portability?</li>
</ul>

<p>To the last question if you say <strong>power</strong> you get a 13" MBP, if you say <strong>price</strong> you get a MacBook and if you say <strong>portability</strong> you get a MacBook Air. Yes there is then the case of choosing which model, but again that comes down to a question of price vs power. The rest is just tweaking.</p>

<p>You want to take away the pressure of choice, you want to choose for them. 99 potential customers may want A and 1 may want B. Ignore the one that wants B. Don't even give users the choice between A and B. Sure you've made 1 person unhappy, but you've made 99 people happy.</p>

<p>The only time you should give the choice to your customers is if there is a really significant minority. Say it was 60 people wanted A and 40 wanted B. That is when you should consider whether adding the choice between A and B outweighs having 66% more people buy your product</p>

<p>The problem is that many people who make the decisions about whether to add a choice are tinkerers and often think "we'll I'd like to tinker around so others might". This leads to the technology we have today which does a hell of a lot of stuff, but which most people don't care about.</p>

<br/>
<h3>Tinkering Is Vital</h3>

<p>Bullshit. I hear this a lot and that is all it really is. Lets look at 2 quotes from a <a href="http://www.boingboing.net/2010/04/02/why-i-wont-buy-an-ipad-and-think-you-shouldnt-either.html">post by Cory Doctorow on BoingBoing</a>.</p>

<blockquote>The original Apple ][+ came with schematics for the circuit boards, and birthed a generation of hardware and software hackers who upended the world for the better. If you wanted your kid to grow up to be a confident, entrepreneurial, and firmly in the camp that believes that you should forever be rearranging the world to make it better, you bought her an Apple ][+.</blockquote>

<p>The idea that having a product that you can tinker with is what allows you to be creative or confident is silly. Technology is a tool. Knowing what is in it and hacking around with it is something a small minority have any interest in or find useful. Far more people care about using tools than what makes them.</p>

<p>Sure, tinkering can be fun to many people, but making tinkering easier for a few could make it a worse tool for everyone else. Lets take the example of the iPad. It could be made easier to tinker with, if you added screws to it to take it apart. However, adding screws increases costs, reduces aesthetics and, if you are also going to lay things out best to those wanting to tinker, could increase the size of the product. How many people would want the ability to take something apart over a cheaper, smaller more aesthetically pleasing product? <strong>VERY</strong> few.</p>

<blockquote>Buying an iPad for your kids isn't a means of jump-starting the realization that the world is yours to take apart and reassemble; it's a way of telling your offspring that even changing the batteries is something you have to leave to the professionals.</blockquote>

<p>This is just crazy talk. Sure, you could allow user replaceable batteries, but again like above it leads to a worse product. You have to add a mechanism for the battery to go in, to keep it in place and to encase the actual battery itself. This leads to more weight, more parts so more chance for failure and higher costs and also less space for the actual battery, so lower battery life. Now how many people would choose an easily (because you will be able to do it yourself if you really wanted to) user replaceable battery over a lighter, cheaper, more reliable product with greater battery life? Again, <strong>VERY</strong> few people.</p>

<p>Now let's think about something fundamental to economics: what are we buying? Contrary to popular belief, we are rarely buying a product. What we are buying is experience and knowledge. When I buy a mobile phone, I am paying for the experience and knowledge of the people that designed it and assembled it. I could, if I really wanted go and design and build my own. But my time is worth more to me than that.</p>

<p>An even better example is visiting a doctor. Why do I go and see a doctor rather than treat myself? Because they have done 5+ years of learning and experience. They know a hell of a lot more than I do. Sure I could go on the internet to find out why I'm ill, but is it really worth it if I'm wrong?</p>

<p>People are willing to pay for stuff that makes their life easier, that means they don't need the knowledge and experience themselves. This is why people pay a mechanic to fix their car or pay a chef in a restaurant to cook a greta meal or pay a company to replace a battery.</p>

<br/>
<h3>Tinkering doesn't matter</h3>
<p>As much as some people like to try and convince you that tinkering is key to our freedom, our progress and our existence, they really mean "tinkering is key to my hobby". You don't need to tinker to learn something. Most of my learning was done through reading, watching and listening. Sure it is a way to learn, but it is far from the only way.</p>

<p>People who want to tinker will find a way to tinker, even if it is harder. I can still open an iPhone if I want to, I can still install different software. It just isn't easy and for that I am grateful, because it means that what came out of it was a product that I care less about how it works and more about what I can do with it. The sooner we get more products like this, the sooner we can have technology that is made for the majority, not the minority of tinkering geeks.</p> 
      ]]></content>
    </entry>

    <entry>
      <title>Code Collector Pro 1.4</title>
      <link rel="alternate" type="text/html" href="http://www.mcubedsw.com/blog/index.php/site/code_collector_pro_1.4/" />
      <id>tag:mcubedsw.com,2010:blog/index.php/site/comments/1.103</id>
      <published>2010-03-31T14:42:04Z</published>
      <updated>2010-06-26T18:26:05Z</updated>
      <author>
            <name>M Cubed</name>
            <email>pilky@mcubedsw.com</email>
                  </author>

      <category term="Code Collector" scheme="http://www.mcubedsw.com/blog/index.php/site/C1/" label="Code Collector" />
      <content type="html"><![CDATA[
        <p>511 days. That is how long it has been between Code Collector Pro 1.3's release and the release of 1.4 (the geek inside of me now makes me wish I'd waited until tomorrow for a nice round 512 days). Yet despite this large amount of time, CCP 1.4 is admittedly lacking in new features. It has a lot of user interface re-design and bug fixes but in terms of new features, the most significant is probably being able to see the dates a snippet was added and last modified.</p>

<p>So why has it been so long between the two releases, and why has there seemingly been so little changed? This blog post is to answer those two questions.</p>


<br/>
<h3>Why so long?</h3>
<p>Put simply, finishing my Computer Science degree got in the way. I release CCP 1.3 in November 2008. At this point my first dissertation deadline was approaching fast and so after I released 1.3 I had to focus on that (my dissertation contributing to over a third of the marks for my entire degree). My final deadline for my dissertation was late-April 2009 and from then until the end of May I had exams to revise for and take. Finally, come the 28th of May 2009, I was free and able to go full time with M Cubed.</p>

<p>But wait? That was 9 months ago, what have I been doing in the intervening time? Well first off I joined up with Fabio to start the design side of M Cubed which required management. And also I had to work on Minim 2.0 which was a complete re-write. Both of these required more time than I was expecting at first and so it was January before I could start work on CCP 1.4, which then took longer than I was expecting itself.</p>

<br/>
<h3>Why so little?</h3>
<p>So why is there so little new feature wise in CCP 1.4? Well, put bluntly the code in 1.3 sucked. I have talked about why in a <a href="http://www.mcubedsw.com/blog/index.php/site/comments/size_matters/">previous post</a>, but in a nutshell it had a lot of 10.4 era code and was designed by someone much less experienced in software than me: me circa 2 years ago.</p>

<p>After hardly touching the code for over a year, when I came back to it I found I needed to re-write lots of it. In fact about 60% of the code in CCP has either been re-written or moved around between 1.3.6 and 1.4. A lot of old code was deleted with more modern alternatives put in its place. Essentially this re-write will make it easier to add newer features in 1.5 and 2.0. So while it doesn't add much now, it will allow me to add better features in the future at a faster pace with hopefully fewer bugs.</p>

<br/>
<p>So make sure you checkout <a href="http://www.mcubedsw.com/software/codecollectorpro">Code Collector Pro 1.4</a>. While there isn't much new, there is a lot of stuff that has been massively improved. There's also a screencast showing some features that have been around for quite a while, but many people don't seem to know about.</p> 
      ]]></content>
    </entry>

    <entry>
      <title>Building a Modern Cocoa App</title>
      <link rel="alternate" type="text/html" href="http://www.mcubedsw.com/blog/index.php/site/building_a_modern_cocoa_app/" />
      <id>tag:mcubedsw.com,2010:blog/index.php/site/comments/1.102</id>
      <published>2010-03-04T17:13:56Z</published>
      <updated>2010-06-26T18:25:57Z</updated>
      <author>
            <name>M Cubed</name>
            <email>pilky@mcubedsw.com</email>
                  </author>

      <category term="Coding" scheme="http://www.mcubedsw.com/blog/index.php/site/C2/" label="Coding" />
      <content type="html"><![CDATA[
        <p>A while back I wrote <a href="http://www.mcubedsw.com/blog/index.php/site/comments/size_matters/">a post</a> on how I was pushing towards making my apps much more manageable, by separating my once monolithic app delegates and nibs into various view and window controllers. Yesterday Justin Williams wrote a post on his blog about <a href="http://carpeaqua.com/2010/03/03/getting-started-with-core-data-bindings-and-nsviewcontroller/">Getting Started with Core Data, Bindings and NSViewController</a>.</p>

<p>Cocoa has changed a lot over the years. I started programming on 10.3, when Xcode was a version 1.0 and Bindings, KVO and KVC were the new hotness. Over subsequent releases we gained Core Data, Objective-C 2.0, NSViewController, Garbage Collection and much more. I strongly believe that any modern Cocoa app should be using Core Data, Objective-C 2.0, Garbage Collection and NSViewController. Bindings should also be used where appropriate (I'll define where I think this is later).</p>

<p>Justin's post included a project he'd worked on, implementing core data tutorial application from <a href="http://cocoadevcentral.com/articles/000085.php">CocoaDevCentral</a> using several window and view controllers rather than one monolithic class and nib. The way he built his version was quite interesting, as it was differently to how I would have approached the task. As it was a relatively simple project, I thought it would be of benefit to some to provide an alternate way of building the same app. I don't think there has been two Cocoa developers giving two different ways of implementing an entire app before.</p>

<p>You can download the source for my version <a href="http://www.mcubedsw.com/downloads/blog/M3MasterDetailVC.zip">here</a>. I also recommend downloading <a href="http://github.com/carpeaqua/MasterDetailVC">Justin's version</a>. I'll first outline how Justin's implementation works and then go into how my implementation works and how it differs from Justin's.</p>
<br/>
<h3>The Application</h3>

<p>But first it would make sense to outline the application. It is a simple blogging app. It consists of a main window containing a splitview. On the left is a list of posts, with an add button below. On the right are the details of the current post: the title, author, category and body. The author and category are chosen from a list which can be edited by clicking the edit button next to the field. This brings up a panel allowing editing of the author and category lists.</p>

<img src="http://www.mcubedsw.com/images/blog/masterdetailvcmain.png" alt="Main window"/>

<p>The data model is as shown below:</p>

<div align="center"><img src="http://www.mcubedsw.com/images/blog/masterdetailvcdatamodel.png" alt="Data Model" class="blogimg"/></div>

<br/>
<br/>
<br/>
<h3>Justin's Implementation</h3>
<p>Justin has structured the application as 3 window controllers, 2 view controllers and the app delegate:</p>

<ul>
<li><strong>MDVCAppDelegate</strong> contains all the code to initialise the Core Data store and the main window controller. It also inserts the initial authors and categories if the database is empty.<br/><br/></li>

<li><strong>MDVCMainWindowController</strong> is the window controller for the main window. When the window is loaded it initialises the view controllers and adds their views to the splitview, and sets up the frame and autoresizing mask.<br/><br/>

Perhaps the most interesting part of the whole implementation is that it uses a single NSArrayController in the main window's NIB, which is then passed to the view controllers when they are initialised. This array controller is in entity mode and bound to the managedObjectContext on the application's delegate. The add button's action is connected to the array controller.<br/><br/></li>

<li><strong>MDVCPostsListViewController</strong> is a very light weight class. It just handles initialisation and pushes all the handling into the NIB. The table column is bound to the array controller that was passed in at initialisation<br/><br/></li>

<li><strong>MDVCPostDetailViewController</strong> is almost identical to the posts list view controller, except that it includes methods to show the authors and categories lists. It uses the selection on the passed in array controller to fill in the details. The NIB also contains array controllers for the authors and categories lists, which are bound to the app delegates managed object context.<br/><br/></li>

<li><strong>MDVCCategoriesWindowController</strong> is just a singleton that sets up the main window. Again, most of the logic is pushed to the NIB with an NSArrayController handling everything.<br/><br/></li>

<li><strong>MDVCAuthorsWindowController</strong> is identical to the categories window controllers, except that it handles authors<br/><br/></li>
</ul>

<p>And that is all there is to Justin's implementation. It is very simple and most of the processing is pushed off to Core Data and NSArrayController.</p>

<br/>
<h3>My Implementation</h3>

<p>I built my implementation with the same structure as my 3 existing apps. Rather than relying on core data and bindings completely, I use KVO manually and have a model controller that wraps around core data. I have a similar set up in terms of controllers: 3 window controllers, 2 view controllers and the app delegate. But I also have 9 extra classes, my model controller, 2 classes to simplify core data and 6 model classes generated by <a href="http://github.com/rentzsch/mogenerator">MOGenerator</a>.</p>

<ul>
<li><strong>M3MasterDetailVC_AppDelegate</strong> handles all the window controllers. In this case, all the window controllers are application global. As such I prefer to put the code handling them into the app delegate. You may be wondering how the editAuthors: and editCategories: methods are called, and all will be explained later in the post.<br/><br/></li>

<li><strong>M3MainWindowController</strong> holds and mangages the view controllers. It initialises the view controllers in its init method and adds them to the split view in awakeFromNib. The two subviews of the splitview are connected to IBOutlets. The code for creating a new post is also in here, as I'm no longer relying on bindings for adding and removing objects.<br/><br/>

There is also the first bit of KVO usage. The window controller observes the selectedPost property on the posts list controller. When this changes it sets the post of the details controller to the newly selected post.<br/><br/></li>

<li><strong>M3PostsListViewController</strong> provides 5 important methods. The first returns an array of posts from the model controller. This is used by the array controller in the NIB as its contentArray. The array controller is this time used in class mode, rather than entity mode, with the contained class set to M3Post. The reload data method tells KVO that the posts array has changed, which causes the array controller to refresh.<br/><br/>

The selected post method returns the post object that is currently selected in the array controller, if there is one. Conversely selectPost sets the selected post on the array controller. And finally there is the tableViewSelectionDidChange: delegate method, which informs KVO that the selectedPost changed whenever the table selection changes.<br/><br/></li>

<li><strong>M3PostDetailViewController</strong> only contains code for observing and returning the list of authors and categories. Most of the logic is in the nib, where an NSObjectController represents the selected post. Other than this the NIB is almost identical to Justin's version<br/><br/></li>

<li><strong>M3AuthorsWindowController</strong> contains code for listing, adding and deleting authors. The authors are displayed in the UI via an NSArrayController whose content array is set to the authors array. The add and delete actions are connected to the class which calls the model controller and invokes the appropriate KVO methods.<br/><br/></li>

<li><strong>M3CategoriesWindowController</strong> is identical to the authors window controller, except that it deals with categories<br/><br/></li>

<li><strong>M3ModelController</strong> is the main difference in the two implementations. It provides a single focus point through which all data creation, deletion and retrieval flows. While this may seem like overkill for this application, where bindings are pervasive, it is a very useful thing to have when you do a lot of work with data that doesn't involve bindings.<br/><br/>

The init methods sets up a core data manger and a simple core data instance. It also checks if the database is empty (there are no authors) and if so inserts the initial content. The rest of the methods just deal with returning, creating or deleting objects.<br/><br/></li>
</ul>

<p>The following two classes I group together as M3CoreData. They are classes I've built that make CoreData cleaner and simpler to access.</p>
<ul>
<li><strong>M3CoreDataManager</strong> is where all the CoreData initialisation code that often resides in app delegates is pushed off to. It doesn't do anything special, it just makes life cleaner by pushing all the code you don't care about off into a class and putting the bits you do care about into an initialisation method.<br/><br/></li>
<li><strong>M3SimpleCoreData</strong> is where I encapsulate the code required to add and retrieve objects with core data. This code is very samey and very tedious and there's no good reason to write it every time. <br/><br/></li>
</ul>

<p>And finally there are the 6 classes generated by MOGenerator. I've learned to swear by MOGenerator for my core data applications, it is removes all the hassle that you would otherwise have if you used Xcode's built in tool for generating model classes for core data entities. The only change from the generated code is an awakeFromInsert method in M3Post that sets the creation date.</p>


<br/>
<h3>Responder Chain Hacking</h3>
<p>One thing I like to do is abuse the responder chain (please don't call the police!). In larger applications I make sure every view and window controller on screen is in the responder chain. This has the advantage of being able to put methods where they belong, rather than where you can access them. For example, the newPost: method is in the window controller. In some of my apps I have it in the side bar controller, because that is all that cares about adding a post.</p>

<p>You can then connect you actions to the first responder proxy in the NIB. It will traverse the responder chain and find the appropriate class and then invoke the method. You can then control whether the method can be invoked by overriding respondsToSelector, which will give you menu validation control.</p>

<p>This is how the editAuthors: and editCategories: methods in the app delegate are called. The buttons in the details view are connected to these methods via the first responder proxy. As the app delegate is in the responder chain it will be the one receiving the methods (as nothing else futher up the chain implements them).</p>

<br/>
<h3>Where To Use Bindings</h3>
<p>Bindings are a contentious issue. Some people love them, some people hate them. The fact is that they are incredibly useful and can save a LOT of code. To give one example, the new inline inspector in CCP 1.4 was initially all handled in code. Unfortunately this required a lot of logic for handling no selection, multiple selections etc. In the end I just replaced the code with bindings to an NSArrayController and managed to delete around 100-150 lines of code.</p>

<p>But bindings aren't useful in all cases. Over the years I've kept changing how I use bindings. I used to use them everywhere, then went through a phase where I didn't use them at all, but have now settled on a good middle ground, where I use them where they work best. So where is that?</p>

<ul>
<li><strong>Preferences</strong> - bindings are ideal for handling your preferences. Most preferences are just booleans, strings or integers, handled by checkboxes, text fields and popup lists/radio buttons. These can be bound directly to the shared user defaults controller and remove the vast majority of code from your preferences controller.</li>
<li><strong>Forms</strong> - this is sort of a superset of the preferences use case. Anywhere that you have a form for displaying and/or editing data on an object (or especially in cases of multiple selections), you should use bindings. It saves on a huge amount of code and it handles all the issues of editing multiple items at once, populating pop up lists etc</li>
<li><strong>Simple Tables</strong> - I have found that any sort of simple table should be implemented using bindings. By simple I mean ones that don't require any complicated logic in the data source. If you just have an array of objects and you want to display their properties in a table, use bindings, it is much simpler. However, do <strong>NOT</strong> use bindings for outline views. NSTreeController is evil and should be avoided like the plague. Consider this a public service warning, just avoid it and save yourself a lot of pain.</li>
</ul>

<br/>
<h3>Use New Tech, It's There For A Reason</h3>
<p>There are a lot of people who avoid some of the new technology in Cocoa. Some don't like Core Data because it seems like voodoo (if you learn a little bit more you'll actually find that it is quite simple, yet incredibly powerful) and some dislike Garbage Collection because of experiences with other garbage collectors (in reality the GC in Obj-C not only saves you the pain of memory management but also of threading, while also potentially being faster than a retain/release system).</p>

<p>You should always be looking at the new technology that comes in each release of Cocoa, most of it can save you 100s, if not 1000s of lines of code if you can adopt it. It can also make the code you do have much easier to manage. It seems odd that most people would agree it is insane to write and use an alternative to something like NSTextView, yet will write and use an alternative to some more modern technology in Cocoa.</p> 
      ]]></content>
    </entry>

    <entry>
      <title>Version Control UI Design</title>
      <link rel="alternate" type="text/html" href="http://www.mcubedsw.com/blog/index.php/site/version_control_ui_design/" />
      <id>tag:mcubedsw.com,2010:blog/index.php/site/comments/1.101</id>
      <published>2010-02-12T11:01:47Z</published>
      <updated>2010-06-26T23:59:48Z</updated>
      <author>
            <name>M Cubed</name>
            <email>pilky@mcubedsw.com</email>
                  </author>

      <category term="Coding" scheme="http://www.mcubedsw.com/blog/index.php/site/C2/" label="Coding" />
      <content type="html"><![CDATA[
        <p>As with many of my blog posts, it is often a tweet or another blog post that made me want to write my thoughts. In this case it is both:</p>

<blockquote>Just accidentally blew away 16 files' & days' worth of work with hg. Looked up, TIme Machine had just finished. Lost < 1 min. of work.</blockquote>
<h5>- <a href="https://twitter.com/incanus77/status/8978633023">@incanus77</a></h5>

<p>That tweet prompted Wolf Rentzsch to write this post about how <a href="http://rentzsch.tumblr.com/post/384353696/time-machine-your-version-control-safety-net">Time Machine is your version control "safety net"</a>. To me both of these are shocking. It seems that the tweeted mishap may have been user error, but it made me look into how the various user interfaces help protect the user.</p>

<br/>
<h3>Your VCS should protect you</h3>
<p>For a long while I was opposed to VCSs, mostly due to faffing around with subversion and getting nowhere. With DVCSs I've become an addict. The issue is that DVCSs also try to be clever. Their primary goal is to protect you from yourself, to make sure your code and its history are safe. Essentially your commit history should be like a stack. 99% of the time you push onto the stack, rarely you need to pop off a stack. You can read the contents of the stack as you want. But you shouldn't be able to modify the internals of the stack.</p>

<p>This is why I consider the many rebase plugins/commands in DVCSs to be harmful. I feel that rebase should be viewed as a mixture of goto, premature optimisation and Jeremy Kyle all rolled into one ie don't touch it unless you know what you're doing and are wearing many layers of protection, and even then it probably isn't such a good idea. Some people swear by rebase, but I feel that you shouldn't be messing with what should be treated as sacred.</p>

<h2 style="text-align:center">Your repository is not a toy, so stop playing with it.</h2>
<br/>
<h3>Protecting against destructive actions</h3>
<p>This is where we get onto UI. I've never really given much thought to command line UIs, but comparing git, Mercurial and Bazaar I've found subtle differences in the UI that make it harder or easier for a user to perform a destructive action. These really fall into 3 categories: confirmations, making it hard to destroy and separating destructive actions.</p>

<p>In the case of the tweet at the start, I looked into the command that was performed: <code>hg update -C </code>. It offers no confirmation dialogue, it just cleans out the items that have changed. It doesn't make it hard to destroy changes and it is a one character option which means it is easy to do. I'm not sure about git but the equivalent in Bazaar would be <code>bzr revert --no-backup</code>. Of course there's no real reason to run --no-backup, it helps save your arse just in case and cleaning it up is just a case of <code>bzr clean-tree --detritus</code> (which lists the files to be deleted and asks for a confirmation).</p>

<p>One of the other examples is from the blog post. <code>git branch -d abranch</code> will delete the branch called abranch. Now to me this seems incredibly dangerous as there isn't any confirmation given. Occasionally I've seen warnings to use the uppercase -D option if changes aren't merged into the parent, but sometimes even those may not appear. If you're doing something like deleting a branch then it should be made harder to do. Really it should be <code>git branch --delete-branch abranch</code> and then ask you to confirm the delete.</p>

<p>Destructive actions should really be moved out into other commands if possible. bzr has 2 such commands: uncommit and clean-tree. Uncommit and clean-tree both list the items that will be removed and ask you to confirm. This makes the user double check what they're doing to confirm what they are doing. Now these commands could be moved into other commands. Uncommit could be made into <code>bzr commit -d</code>, but by separating them out you are making the user think that this is a different thing and making it harder for them.</p>

<br/>
<h3>The hypocrisy of UI design</h3>

<p>It does seem very hypocritical, when most of UI design is a push to make life easier for a user, to advocate making it harder. But as odd as it may seem, making something harder may make it more usable. Now by harder I don't mean make a series of convoluted steps that require an animal sacrifice. I mean add an extra step to any potentially dangerous action. Tell the user exactly what the result of the action will be and ask them to confirm it.</p>

<p>Obviously you should provide undo when possible, but sometimes it isn't. Think about where in your UI you place these actions and consider whether you need them there at all. Don't put a 'wipe library' button right next to one of the most commonly used buttons in your UI, and no matter where you put it, if you can't offer an undo then tell the user exactly what you will do and make them confirm. Force them to pay attention to what they are doing. They'll thank you for it, even if it is just by not complaining to you (or worse to the internet) about how your software lost their data without warning.</p> 
      ]]></content>
    </entry>

    <entry>
      <title>The Rules of Communication</title>
      <link rel="alternate" type="text/html" href="http://www.mcubedsw.com/blog/index.php/site/the_rules_of_communication/" />
      <id>tag:mcubedsw.com,2010:blog/index.php/site/comments/1.100</id>
      <published>2010-02-05T21:28:43Z</published>
      <updated>2010-06-26T18:25:44Z</updated>
      <author>
            <name>M Cubed</name>
            <email>pilky@mcubedsw.com</email>
                  </author>

      <category term="Coding" scheme="http://www.mcubedsw.com/blog/index.php/site/C2/" label="Coding" />
      <content type="html"><![CDATA[
        <p>At NSConference <a href="http://www.dribin.org/dave/">Dave Dribin</a> made the following statement in a slide:</p>

<blockquote>Delegates are preferable to Notifications which are preferable to KVO</blockquote>

<p>Now this caused a bit of a murmur on Twitter, as it was taken as "KVO is bad". As this is an important topic and not one that can easily fit into 140 characters I thought I would write a post to outline my rules for when to use each technology and why use them where I do.</p>

<br/>
<h3>Rule #1: Always use delegates for 1 to 1 relationships</h3>
<p>One of the main reasons delegates were listed as the most preferable is that they provide the least 'magic' way of communicating between objects while keeping them loosely coupled. It sends the message directly to the object and you can see what method is being run. As such it makes your code more self explanatory. So whenever you have a 1 to 1 relationship between two classes, opt for delegation over notification.</p>

<br/>
<h3>Rule #2: Use notifications for communicating events to many objects</h3>
<p>Notifications should really be used wherever you would use a delegate, but need to communicate with any number of objects. They should really be thought of as 1 to many delegates. Quite often in Cocoa you will see a case where there is a notification and a delegate method for the same event (eg change of selection in a table view). These are cases where 80% of the time you just need a 1 to 1 relationship, but occasionally do need a 1 to many relationship. You will rarely encounter this in your own code, unless you are building a class for use in multiple apps.</p>

<br/>
<h3>Rule #3: Use KVO for communicating data model changes</h3>
<p>This is where I have found KVO to be the most powerful. You need to keep various UI elements in sync with your data model. Changing the value of the model from one view should also update the value in other views. KVO was built for exactly this situation and as such requires much less code than delegation and notifications.</p>

<p>To achieve the same effect with delegation or notifications you would have to add delegate methods or post a notification in each setter method of each model object. This obviously is a lot of code that needs to be written. Code that could have bugs and code that makes your source more cluttered. KVO of a value in an object requires just one line of code and the implementation of one method. And if you use bindings then it is actually no code at all.</p>

<br/>
<h3>Rule #4: Use blocks instead of callback delegates</h3>
<p>I'll start with the exception to this: if you have multiple callback options then use delegates (eg NSURLConnection). But the vast majority of asynchronous operations need just a single callback. In these cases, if you are using Mac OS X 10.6, then you should be using blocks instead of delegates. Blocks reduce the layer of indirection in your source by putting the call back information inline with the invocation of the method.</p>
<br/>
<p>The next two rules aren't quite rules of communication, but are relevant to the discussion at hand.</p>

<br/>
<h3>Rule #5: Comment anything that isn't clear</h3>
<p>This should be pretty obvious. If something in your code isn't explicitly clear from the code itself then comment it. If you are sending off a notification say why you are sending it off, so you can get an idea of what it is doing elsewhere in the application.</p>

<br/>
<h3>Rule #6: If something seems like magic, learn how it works</h3>
<p>There is no such thing as magic in programming, simply things we don't fully understand. If notifications, delegation, KVO or anything else seems like magic, then read up the documentation on it or ask a developer experienced in that area to explain how it works. When you find out how they work you realise that what seems like magic is fundamentally a very simple process.</p>

<br/>
<p>Ultimately, what Dave said was right for some scenarios. Each technology has its use case and you should only use it where it is needed. You should always aim for the smallest amount of indirection in your code while still retaining loose coupling of classes. KVO and notifications are necessary in some occasions (unless you want to go crazy with delegation) but they should only be used when they are needed.</p>
 
      ]]></content>
    </entry>

    <entry>
      <title>Thoughts on the iPad</title>
      <link rel="alternate" type="text/html" href="http://www.mcubedsw.com/blog/index.php/site/thoughts_on_the_ipad/" />
      <id>tag:mcubedsw.com,2010:blog/index.php/site/comments/1.99</id>
      <published>2010-01-28T17:48:32Z</published>
      <updated>2010-06-26T18:24:33Z</updated>
      <author>
            <name>M Cubed</name>
            <email>pilky@mcubedsw.com</email>
                  </author>

      <category term="General" scheme="http://www.mcubedsw.com/blog/index.php/site/C/" label="General" />
      <content type="html"><![CDATA[
        <p>I have seen a lot of questions and comments on the iPad and I feel I need to write my responses to some of them down. So here goes.</p>

<br/>
<h3>Who is the iPad for?</h3>
<p>The iPad is for casual computing. It is what many people said the iPhone would be for, before realising that the small screen isn't all that good for casual computing. The iPad really is a remarkable device, showing off the technology combination the iPhone introduced us to in a much better way.</p>

<p>But who is it for? Well it is for everyone. Some people are saying it is for their parents and that it isn't for geeks or professionals. I disagree. Yes it is ideal for those who don't want to learn how to use a computer, but that doesn't mean that it won't also be great for the computer literate. Hell, look at the popularity of the iPhone, that isn't just computer illiterate users. But just because it will work well for everyone, doesn't mean it will work well for every task.</p>

<br/>
<h3>What is its place?</h3>
<p>Apple explicitly said that the iPad sits between the iPhone and the Mac. They have specced it out in that range, are marketing it in that range and priced it in that range. It sits in the middle ground, which is exactly the same place that many low end PCs sit. The exact sort of PCs that are bought for workers, schools or just by people who want a computer to get online but don't need anything powerful.</p>

<p>Think of all the people who have to travel around with bulky laptops just to fill out some forms when they see customers. The iPad is a much more portable way of providing that same functionality, for what would be a reasonably similar price.</p>

<p>In education the iPad would be invaluable. With the iBooks system, iTunes U, iWork all on this one lightweight device which costs only a bit more than a low powered laptop, it is the perfect education tool. It becomes the textbook, the educational video and the work machine all in one. With the ability to type but also sketch with your finger it could replace pen and paper for note taking for many people.</p>

<p>And finally think of the casual user. You don't need a bulky computer system any more, you can buy a sleek iPad that you can easily store in a drawer when you don't need it. It is powerful enough for everything a casual user could want, and then some. There is also something else significant I will get to in a bit.</p>


<br/>
<h3>Isn't it just a big iPhone?</h3>
<p>From a technical point of view it pretty much is just a big iPhone. Sure it is faster and has different UIs on the apps, but it is running the same fundamental core. But it is very easy to underestimate how important the bigger screen is. There are many applications that work ok on the iPhone but would work so much better on an iPad</p>

<p>In the keynote video the developer of <a href="http://brushesapp.com/">Brushes</a> was brought on stage to show off the app. The extra screen space allows a much bigger canvas with more powerful tools. The iPhone lets you build a toy paint app, the iPad lets you build a real paint app.</p>

<p>The iPhone also doesn't really work for things such as office applications. Pages, Keynote, Numbers. Sure you <i>could</i> do them on the iPhone, but they wouldn't provide a good experience. The iPad offers a screen resolution that allows you to make these sorts of applications possible.</p>

<p>The other key thing is that there are some app concepts that work well on the iPhone but not on the Mac. There are also some that work well on the Mac but not on the iPhone. On the iPad the majority of these concepts from Mac and iPhone work equally well. You can build desktop calibre apps for the iPad, which you couldn't for the small screen of the iPhone.</p>

<br/>
<h3>Surely this means the Mac is dead?</h3>
<p>The iPad replacing the Mac is as likely as it replacing the iPhone. The iPad is a 1GHz device with up to 64GB of storage and a 9.5" screen supporting a 1024x768 resolution. For casual computing that is fine. But for high performance tasks? No. For shared media system? No. For doing work that requires very large amounts of screen real estate? No.</p>

<p>For the iPad to replace the iMac for example it would need to have a 27" screen with 2560x1440 resolution, a 2.6GHz quad core processor and 1TB of storage. The fact is that such a machine would be both hugely expensive and incredibly impractical.</p>

<p>In the same way that an average laptop is always less powerful than an average desktop at any period in time, the iPad will always be less powerful than an average laptop. It is basic economics and physics. New high powered processors produce more heat and so need more cooling, over time processors of equivalent power will be made more efficient and smaller. The iPad is 1GHz, Macs reached 1GHz 8 years ago.</p>

<p>The iPad is also a much more personal device. I wouldn't expect to see many groups of people gathering round an iPad to watch a movie. The Mac provides a much better group media system due to the bigger screen size. Throw in the fact that you can add a remote and front row to the Mac and you have a home entertainment system, which the iPad is not.</p>

<br/>
<h3>So why not just chop the keyboard off a MacBook?</h3>
<p><a href="http://i.imgur.com/Wo27t.jpg">Some people</a> wanted a touch screen Mac with no keyboard or mouse. Such a product would fail miserably. This is essentially what a Windows Tablet/Slate/Whatever-they're-calling-them-this-week is. It is a laptop with the keyboard chopped off. And they provide a terrible experience. Not because of the hardware, but because they're running Windows.</p>

<p>Now that isn't to take a jab at Windows. The issue is that Window is a desktop OS. It has been designed for use with keyboard and mouse and doesn't work too well with a touch screen. Like OS X it has some multi touch functionality hacked on, but you are still moving a mouse cursor about and clicking on a 1px point.</p>

<p>A user interface for a touch screen where the primary input method is your finger requires a hugely different user interface. You can't have a 1 pixel line you have to touch and drag as you do with split views. You need to fundamentally change how controls behave as they need larger target areas.</p>

<p>Many parts of a desktop OS are irrelevant as well. Scrollbars aren't needed on a touch screen. They would take up valuable screen space that can otherwise be done by stroking your finger along the screen. Scroll areas are also inverted. Drag a scroll bar down on a desktop and the page moves down, drag your finger down on an iPhone and the page moves up. This is because you no longer have the disconnect between screen and input device.</p>

<br/>
<h3>What about multi tasking?</h3>
<p>There have been two large groups of people talking about multi tasking. Those who want it and those who think that casual users won't use it. Both groups are right and wrong. The iPad needs multi tasking, but it doesn't necessarily need to mean multiple apps running at once.</p>

<p>For those who don't think it is needed, I would ask whether you multi task in real life? Yes you do. Off the computer you listen to music while you work. On a computer you flip back and forth between a web page and a word processing document. You do multi task.</p>

<p>What you don't do is use 20+ applications all at once. Sure I have over 20 applications open but I don't use them all. As I'm writing this blog post I'm listening to music while flipping between typing up and researching on the web, with the occasional glance at twitter. Now on the iPad I could just exit to the home screen from Pages and open Safari, find what I want then copy and paste back into Pages. Then if I want to change my music I open up the iPod app and change it there.</p>

<p>The issue is that I am multi tasking whether the iPad allows me or not, but I'm having to go through the awkward process of quitting an app, opening another app, quitting that, opening the previous app. There needs to be a limited ability to switch quickly between a certain set of apps.</p>

<p>One way I have thought of is to use a 4 finger swipe. It would work much like 4 finger swiping on a MacBook Pro trackpad. Swipe horizontally and be presented a list of 'open' apps under your finger which you can choose from. Swipe vertically would bring up the home screen to open a new app. This makes the process much faster.</p>

<p>The best thing about this is that it can still be quitting the applications. I'm just not having to move my finger down to the bottom to press the home button, then back up to where I was on the screen to find the app I want (which may or may not be on a different page of apps). It removes the unnecessary movements of the hand as your switching appears under your finger and also reduces any sort of searching your brain has to do as what you want is in a line of a few choices.</p>

<br/>
<h3>Significance of the 3G networking?</h3>
<p>What hasn't been talked about is the significance of the 3G networking deal. This is truly a revolution. No contract, you can sign up and cancel any time you want and it is a low monthly fee. If you only want the one device then this is the easiest way in the world to get on the internet in your own home. No installing filters and routers and modems. No phoning up an ISP to get them to connect you up in the next few weeks.</p>

<p>Sure it isn't the fastest internet, but it is fast enough for most basic uses. This is getting online the Apple way, except unlike the iMac adverts of the late 90s, there really is no step 3.</p>

<br/>
<h3>Final thoughts</h3>
<p>The iPad truly is a revolutionary device to those who can see its potential. To those who can't it is just an expensive, large iPhone. At the same time, it won't replace the Mac or the iPhone, it just isn't in the same market as either of them. It does have a few flaws at the moment but these are easily fixed. What is important is that this is a glimpse of one of the future forms of mainstream computing.</p> 
      ]]></content>
    </entry>

    <entry>
      <title>Design Re-design</title>
      <link rel="alternate" type="text/html" href="http://www.mcubedsw.com/blog/index.php/site/design_re-design/" />
      <id>tag:mcubedsw.com,2010:blog/index.php/site/comments/1.98</id>
      <published>2010-01-27T13:20:37Z</published>
      <updated>2010-06-26T18:25:38Z</updated>
      <author>
            <name>M Cubed</name>
            <email>pilky@mcubedsw.com</email>
                  </author>

      <category term="M Cubed News" scheme="http://www.mcubedsw.com/blog/index.php/site/C3/" label="M Cubed News" />
      <content type="html"><![CDATA[
        <p>Back in July M Cubed started offering design services. This was meant to be an alternate revenue source to our software that we could rely on. Unfortunately this didn't turn out to be the case. While technically M Cubed is a 2 man operation, it is in reality a 1.5 man operation as Fabio has a separate day job.</p>

<p>Having a day job and then coming home and working nights and weekends leads to a person being worn out very quickly. A lot of our design work was being delayed due to Fabio not having the time or energy to do work and this was also filtering down into design for our products. Minim 2.0 was originally planned for a late november release, but delays in design related stuff meant it kept being pushed back.</p>

<p>The delays meant that the money coming in from design wasn't really worth the effort, and I was unable to help as I'm not exactly icon designer material. This has meant we have had to make the decision to stop offering graphic design services. While we were able to deliver what we hope was high quality products, circumstances meant we weren't able to offer high quality service. It is better to not do a job at all than do a bad job.</p>

<p>While we are stopping our graphic design services, we are introducing two new design services where we can offer a high quality of service as they are areas of design I am able to handle myself: Usability and Accessibility.</p>

<p>There are many services available to Mac and iPhone developers for graphic design. A quick google search will bring up pages of people offering icon or UI design services. But there are very few services that focus purely on usability and none that I have seen that focus on accessibility.</p>

<p>So what will our usability and accessibility design services entail?</p>

<br/>
<h3>Usability</h3>
<p>Well in a nutshell, you give us your app and we will pick through the user interface and point out any areas where usability could be improved. We will explain why things are in need of improvement and what items are urgent.</p>

<p>Of course, there are different degrees of usability. You can make any user interface usable, in the sense of doing what the user expects, by following a series of rules. But usability can also be about how a user feels when using your application. Is it just functional or is it enjoyable? Our usability reviews will provide suggestions for areas where your user interface can be re-thought to make it highly enjoyable as well as functional, turning a user who is merely happy with their purchase into one who raves about your app to their friends and co-workers.</p>

<br/>
<h3>Accessibility</h3>
<p>Our accessibility reviews will work in much the same way. We will go through your application and highlight areas where accessibility is lacking and give you details on how to fix them. But we are also going to do something a bit crazy. We will also show you how to find and detect the majority of accessibility problems yourself.</p>

<p>"But surely that is what we're paying you for? What is the point of us coming to you if you're just going to tell us how to do this work for free?". Very good questions. The fact is that 90% of all accessibility work is trivial. While I certainly am not opposed to you giving us your money, I believe that it is ultimately a waste of your money and of our time to keep coming to us for help with trivial matters.</p>

<p>What you may need help designing is the non trivial matters. How do you make a custom control accessible and what should the interaction model be for disabled users? What is the flow of my application like for disabled users? In a way, if our usability design is aimed at abled users of your software, our accessibility design is the exact same thing but for disabled users.</p>

<br/>
<h3>Getting an estimate</h3>
<p>So how do you procure our services? Send us an email with details of your needs to <a href="mailto:design@mcubedsw.com">design@mcubedsw.com</a> and we will get back to you with an estimate of how long we think it will take. We charge an hourly rate so this will give you a good idea of how much you can expect to pay. So get in touch and start getting feedback on the accessibility and usability of your apps today!</p> 
      ]]></content>
    </entry>


</feed>

