tag:blogger.com,1999:blog-255953902024-03-08T17:51:18.095+00:00iamleegDarwin, Mac OS X, Cocoa, OpenStep, NeXTSTEP. Mac security. All the things you expect from a tech blog, including complaints about the temperature of my coffee.Graham Leehttp://www.blogger.com/profile/07305141119009757571noreply@blogger.comBlogger230125tag:blogger.com,1999:blog-25595390.post-19495130291503451082013-02-15T15:51:00.001+00:002015-04-22T15:40:08.438+01:00How to find meIt came to my attention this week that people are finding me via Google, which (unsurprisingly) links to here. I've been blogging for a couple of years at <a href="http://blog.securemacprogramming.com">Secure Mac Programming</a>, and I'm on twitter as <a href="https://twitter.com/iwasleeg">@iwasleeg</a>. I'm +Graham Lee on Google Plus, too. My email is graham at iamleeg dot com.Graham Leehttp://www.blogger.com/profile/07305141119009757571noreply@blogger.comtag:blogger.com,1999:blog-25595390.post-86665316005919651942010-05-12T09:49:00.001+01:002010-05-12T09:49:37.288+01:00LLVM projects you may not be aware ofAll Mac and iPhone OS developers must by now be familiar with <a href="http://llvm.org">LLVM</a>, the Low-Level Virtual Machine compiler that Apple has backed in preference to GCC (presumably at least partially because because GCC 4.5 is now a GPLv3 project, in addition to technical problems with improving the older compiler). You'll also be familiar with <a href="http://clang.llvm.org">Clang</a>, the modular C/ObjC/C++ lexer/parser that can be used as an LLVM front-end, or as a library for providing static analysis, refactoring and other code comprehension facilities. And of course <a href="http://macruby.org">MacRuby</a> uses LLVM's optimisation libraries.<br /><br />The LLVM umbrella also covers a number of other projects that Mac/iPhone developers may not yet have heard about, but which nonetheless are pretty cool. This post is just a little tour of some of those. There are other projects that have made use of LLVM code, but which aren't part of the compiler project - they are not the subject of this post.<br /><br /><a href="http://libcxx.llvm.org/">LibC++</a> is a C++ library, targeting 100% compatibility with the C++0x (draft) standard.<br /><br /><a href="http://klee.llvm.org/">KLEE</a> looks <em>very</em> cool. It's a "symbolic execution tool", capable of automatically generating unit tests for software with high degrees of coverage (well over 90%). Additionally, given information about an application's constraints and requirements it can automatically discover bugs, <em>generating failing tests</em> to demonstrate the bug and become part of the test suite. There's a <a href="http://llvm.org/pubs/2008-12-OSDI-KLEE.pdf">paper describing KLEE</a> including a walkthrough of discovering a bug in <tt>tr</tt>, and <a href="http://klee.llvm.org/Tutorials.html">tutorials</a> in its use.<br /><br /><a href="http://vmkit.llvm.org/">vmkit</a> is a substrate layer for running bytecode. It takes high-level bytecode (currently JVM bytecode or IL, the bytecode of the .Net runtime) and translates it to IR, the LLVM intermediate representation. In doing so it can make use of LLVM's optimisations and make better decisions regarding garbage collection.<br /><br />Graham Leehttp://www.blogger.com/profile/07305141119009757571noreply@blogger.com14tag:blogger.com,1999:blog-25595390.post-65742731690375887272010-04-28T15:52:00.001+01:002010-04-28T15:52:11.284+01:00WWDC dates announcedThe entire of Twitter has imploded after noticing that Apple <a href="http://www.apple.com/pr/library/2010/04/28wwdc.html">has announced the dates for WWDC</a>, this year June 7-11. That's too short notice for me to go, and having only recently started working again after a few months concentrating solely on <a href="http://www.amazon.co.uk/dp/0470525959?tag=thaeofer-21&camp=1406&creative=6394&linkCode=as1&creativeASIN=0470525959&adid=0F11EH4VPQYNFGPM2KXB&">Professional Cocoa Application Security</a>, I can't scrape together the few thousand pounds needed to reserve flights, hotel and ticket at a month's notice.<br /><br />I hope that those of you who are going have a great time. The conference looks decidedly thin on Mac content this year, and while I still class myself as more of a Mac developer than an iP* developer that shouldn't be too much of a problem. The main value in WWDC is in the social/networking side first, the labs second, and the lecture content third - so as long as you can find an engineer in the labs who remembers how a Mac works, you'll probably still have a great week and learn a lot.Graham Leehttp://www.blogger.com/profile/07305141119009757571noreply@blogger.com2tag:blogger.com,1999:blog-25595390.post-86833574729183043602010-04-15T13:32:00.001+01:002010-04-15T13:32:33.142+01:00The difference between NSTableView and UITableViewA number of times, I've chased myself down rat holes in iPhone projects because I've created a design or implementation that assumes <tt>UITableView</tt> and <tt>NSTableView</tt> are similar objects. They aren't.<br /><br />The main problem I come across is related to how the cells are treated in Cocoa and in Cocoa touch. An AppKit table comprises columns, each of which uses a <em>cell</em> to display its content. A cell contains the drawing and event-handling stuff of a view, but nothing to do with its place in the view hierarchy or responder chain. It's essentially a light-weight view. For each row in the table, <tt>NSTableColumn</tt> takes its cell, configures it for the content in that row and then draws the cell at its location in the column. No matter how many rows there are, a single cell is used.<br /><br />UIKit works differently. Of course a <tt>UITableView</tt> only has one column, but it also displays <em>views</em> rather than <em>cells</em>. This is good, but leads to the key distinction that always trips me up: <em>you can't use the same view more than once in a table view</em>. Of course, sections in a <tt>UITableView</tt> will often have more than one row, but each row that is visible on-screen will needs its own instance of <tt>UITableViewCell</tt> (which is a subclass of <tt>UIView</tt>, and therefore a view in the traditional sense rather than a cell). If you try to re-use the same instance multiple times, the table view will configure each row but only the last one it prepared will be drawn.<br /><br />So what's this <tt>-reuseIdentifier?</tt> stuff? That's related to caching views for scrolling. Imagine a table view with 10 rows, of which 4 can be seen on screen at once. Each uses the same type of cell in this example. When the table view first becomes visible there will be 4 <tt>UITableViewCell</tt> instances in use, displaying rows 0-3. Now you start to scroll the view. <tt>UITableView</tt> finds it needs an extra cell to display row 4, which is now partially on-screen and row 0 is starting to slide off. When row 0 disappears completely, the table view could just delete its cell - but rather than do that, it adds it to a queue of reusable cells. When row 5 starts to appear, the table view can re-use the object it's already created for row 0, because it's the same type of cell as the one for row 5 and is currently unused.<br /><br />So, that's that really. Note to self: don't treat UIKit like it's just AppKit, you'll end up wasting a day of code.Graham Leehttp://www.blogger.com/profile/07305141119009757571noreply@blogger.com3tag:blogger.com,1999:blog-25595390.post-36486065424860789692010-04-02T12:20:00.001+01:002010-04-02T12:20:30.628+01:00On writing a bookWell, I've performed my final author's review, and <a href="http://blog.securemacprogramming.com/2010/02/pre-order-professional-mac-security-books/">Professional Cocoa Application Security</a> is all with the printers. This post is about my experiences writing the book, not the book material itself.<br /><br />My original motivation for writing PCAS was that it was a topic someone needed to talk about, and nobody had hitherto done the talking. I was actually initially approached by Wiley to see if I'd write anything at all - their commissioning editor had seen my <a href="http://thaesofereode.info/clocFAQ/">Objective-C FAQ</a> and this blog, and liked my style. I said that I didn't want to write <em>a</em> book, I wanted to write <em>this</em> book. It was the best way I could pay back the community that has helped me so much in the years I've been a Mac developer.<br /><br />It took about 6 months to write the draft - my original estimate was much shorter but once we realised I couldn't meet that we revised it, after which I stayed on track with the updated schedule. That's six months of <em>nearly full time</em> work. Some other books probably don't take so long, but in this case I had set myself a very ambitious scope and needed to research quite a lot of the topics before I could write on them. If you've already got a series of blog posts, training material or something that you just want to turn into a book, I can imagine the drafting process being much quicker.<br /><br />I've found that book authorship is not the best vehicle for self-study. You get a biased view of the material, looking for things that would be interesting to readers rather than things you will need to use yourself. Because the goal of the book is to provide utility to the readers, you end up with a gotcha-oriented approach to research, looking for the subtle benefits or issues that are not obvious on a casual inspection. That said, it was still a good motivation to learn about the technologies I wrote about, so I'm glad I did it. Parts of the writing process were a lot of fun: I got to find out about some cool frameworks and APIs, absorb loads of information and re-emit it in a form that is, I hope, engaging and interesting. I've looked at my bookshelves and have about 6ft of books that I used as source material - and that doesn't include websites, ebooks and journal papers. On the other hand, I'm not going to deny that I had occasional days that just felt like a long slog to get the day's section written. I didn't mind solving hard problems, but there are some subjects that just seem impossible to say anything interesting about. It's when writing those sections that you find yourself staring at a half-written sentence for an hour, wondering just what it was you were thinking when you wrote the ToC.<br /><br />You're not going to get rich off the advance :). I was in a good position where I could live off practically no income while writing, meaning that devoting a few months to producing the drafts was not a problem. What I have become rich in is exposure and recognition, even before the book was published. Because both the proposal and the book content must be peer-reviewed by a technical reviewer, "I am writing a book" says "there are people out there who trust that I know my subject". Of course, "I have written a book and you can read it" carries more weight, so I expect this exposure to increase after publication.<br /><br />I've worked on reviewing proposals too, and the things you really need to make sure if you are trying to punt a proposal to publishers are:<br /><br /><ul><li>You need to tell the publishers that the market for your book exists, who is in that market and how big it is. They're not going to go and look for the buyers on your behalf (but they will get a reviewer to make sure you're not talking bullshit).</li><br /><li>Having identified your reader, the goals and content of the book <em>must be appropriate to the reader</em>. Don't put an introduction to Xcode in your Advanced iPad Apps book, just to make up an example.</li></ul><br /><br />This theme carries on into the review process for the actual content. The technical reviewer (a role I've also taken before) is not just there to check that the code compiles. Responsibilities include verifying the accuracy of the content <em>and appropriateness for the target reader</em>, and indeed review comments I've made on book drafts have been split roughly evenly between "this isn't quite right" and "your reader won't understand this" (though I'm more verbose in the actual review).<br /><br />So, in short, you will not make money writing a book. You will gain kudos and satisfaction. If you've got something that you think the world desperately needs to know, and you know that you can explain it in a way the world will want to pay attention to, then by all means write! If you want to make a few thousand dollars, or want an easy project between apps, then I'd suggest finding something else. Writing's fun, and it's worthwhile, but it's certainly not an easy life.Graham Leehttp://www.blogger.com/profile/07305141119009757571noreply@blogger.com1tag:blogger.com,1999:blog-25595390.post-91150362978765935852010-03-30T12:22:00.001+01:002010-03-30T12:22:44.348+01:00Rehearsals in beta!I have a new application, Rehearsals, an online practice diary for musicians. If that sounds like the kind of thing you're interested in, and you have Mac OS X 10.6 or newer, then please <a href="http://rehearsalsapp.com/download/Rehearsals-1.0d3.zip">download the beta release</a> and test it out. There's absolutely no charge, and if you submit feedback to <tt>support <at> rehearsalsapp <dot> com</tt> you'll be eligible for a free licence for version 1.0 once that's released. There are no limitations on the beta version, so please do download and start using it!<br /><br />You can follow <a href="http://twitter.com/rehearsals_app">@rehearsals_app</a> for updates to the beta programme (new releases are automatically downloaded using Sparkle, if you enable it in the app).Graham Leehttp://www.blogger.com/profile/07305141119009757571noreply@blogger.com0tag:blogger.com,1999:blog-25595390.post-1162048605618497892010-03-02T12:22:00.001+00:002010-03-02T12:22:30.817+00:00How to hire Graham LeeThere are few people who can say that when it comes to Cocoa application security, they wrote the book. In fact, I can think of only one: me. I've just put the final draft together for <a href="http://www.amazon.co.uk/gp/product/0470525959?ie=UTF8&tag=thaeofer-21&linkCode=as2&camp=1634&creative=6738&creativeASIN=0470525959">Professional Cocoa Application Security</a><img src="http://www.assoc-amazon.co.uk/e/ir?t=thaeofer-21&l=as2&o=2&a=0470525959" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /> and it will hit the shops in June: click the link to purchase through my Amazon affiliate programme.<br /><br />Now that the book's more-or-less complete, I can turn my attention to other interesting projects: by which I mean yours! If your application could benefit from a developer with plenty of security experience and knowledge to share in a pragmatic fashion, or a software engineer who led development of a complex Cocoa application from its legacy PowerPlant origins through Snow Leopard readiness, or a programmer who has worked on performance enhancement in networking systems and low-level daemon code on Darwin and other UNIX platforms, then your project will benefit from an infusion of the Graham Lee magic. Even if you have some NeXTSTEP or OPENSTEP code that needs maintaining, I can help you out: I've been using Cocoa for about as long as Apple has.<br /><br />Send an email to <tt>iamleeg <at> securemacprogramming <dot> com</tt> and let's talk about your project. The good news is that for the moment I am available, you probably can afford me[*], and I really want to help make your product better. Want to find out more about my expertise? Check out <a href="http://www.mac-developer-network.com/category/shows/podcasts/mdnshow/">my section on the MDN show</a>, and the <a href="http://www.mac-developer-network.com/category/columns/security/">MDN security column</a>.<br /><br />[*] It came up at <a href="http://www.nsconference.com/">NSConference</a> that a number of devs thought I carry a premium due to the conference appearances, podcasts and other material I produce. Because I believe that honesty is the best policy, I want to come out and say that I don't charge any such premium. My rates are consistent with other contractors with my level of experience, and I even provide a discounted rate for NGOs and academic institutions.Graham Leehttp://www.blogger.com/profile/07305141119009757571noreply@blogger.com1tag:blogger.com,1999:blog-25595390.post-40584808662355687642010-02-09T10:36:00.001+00:002010-02-09T10:36:00.620+00:00On multitaskingTidBITS unwittingly hits the nail on the head while <a href="http://db.tidbits.com/article/10989?rss&utm_source=feedburner&utm_medium=feed&utm_campaign=Feed:+tidbits_main+(TidBITS:+Mac+News+for+the+Rest+of+Us)">talking about iPad OS multitasking</a> (emphasis added):<br /><br /><blockquote>It's easy to imagine wanting to use an iPad to read text in Mobile Safari, copy some text to a Pages document, and send that document to a colleague via Mail. <em>That specific example may turn out to be possible with the current iPhone OS,</em> but it points toward needing more ways for iPad apps to work together in the future.</blockquote><br /><br />Let me break down the user's workflow here:<br /><ol><li>User reads text in Mobile Safari.</li><br /><li>User copies text to a Pages document.</li><br /><li>User e-mails that document to a colleague.</li></ol><br />The flow of tasks is <em>linear</em>. The user does not need Mail open while reading the text in Safari, nor Safari open while pasting text in Pages. Whether a platform supports multiple simultaneous applications or not, users typically work with one at a time.<br /><br />The advantage of multiple open apps is that the user can switch tasks really quickly (the other oft-quoted benefit, of being able to see context in multiple places at the same time, is actually a feature of a windowing UI: a different technology, and one that iPhone OS lacks). The disadvantage is a technical one—the operating system must allocate resources to applications that the user isn't currently working with. The iPhone (and, I presume, the iPad) provides fast task-switching anyway, through its recommendation that app developers retain app state on termination and recover it on launch. The act of moving between apps via the home screen is supposed to <em>feel</em> like switching tasks, even if it's implemented by a kind of pause-and-resume.Graham Leehttp://www.blogger.com/profile/07305141119009757571noreply@blogger.com4tag:blogger.com,1999:blog-25595390.post-23836265712268102492010-02-04T10:40:00.001+00:002010-02-04T10:40:48.469+00:00Core Data Haiku competition results!I was sent a review copy of <a href="http://www.pragprog.com/titles/mzcd/core-data">Core Data: Apple's API for Persisting Data on Mac OS X</a> by <a href="http://twitter.com/mzarra">Marcus Zarra</a>. The problem is that I already own a copy. So I held a Core Data Haiku competition on Twitter; best haiku about core data posted with the <a href="http://search.twitter.com/search?q=%23coredatahaiku">#coredatahaiku</a> tag wins the book. Sorry if you wrote a great haiku without using the hashtag, but I didn't read it.<br /><br />Anyway, the results. My decision is final, no correspondence regarding the judgement shall be entered into, the squirrel flies south to Leningrad.<br /><br /><h3>Non-entering sample haiku for comparison purposes</h3><br /><br />This is <a href="http://twitter.com/iamleeg/statuses/8626081658">mine</a>:<br /><br />Archiving does not<br/>Make schema changes easy<br/>So <a href="http://search.twitter.com/search?q=%23lickahoctor">#lickahoctor</a><br /><br />very much of its time, you'll agree.<br /><br /><h3>Dishonourable mentions</h3><br /><br />A couple of people sent entries via Facebook, which didn't count within the rules of the game. So without naming the guilty parties:<br /><br />I don't want the book<br/><br />I just like writing haiku<br/><br />Nothing wrong with that!<br /><br />When learning Cocoa,<br/><br />Reasonably new to it,<br/><br />The more books the bett-<br /><br /><h3>Honourable mentions</h3><br /><br />The standard was very high, so I'm pleased to publish every entry, congratulations to you all for some inspired poetry. In a way, there are no losers, because you all helped to make the world a better place. In reverse chronological order (because I'm pasting from the Twitter search page):<br /><br />I do not know what<br/><br />Core data is. Need the book.<br/><br />Please let me win it. — <a href="http://twitter.com/OrigamiTech">OrigamiTech</a><br /><br />Lost In Winter Ills<br/><br />Result Sets Unsorted Again<br/><br />Managed Object Found — <a href="http://twitter.com/chwalters">chwalters</a><br /><br />With multiple stores<br/><br />Inside one application<br/><br />Little kittens weep — <a href="http://twitter.com/inquisitiveCode">inquisitiveCode</a><br /><br />object tree...<br/><br />query is made<br/><br />leaves rustle — <a href="http://twitter.com/ErikAderstedt">ErikAderstedt</a><br /><br />Core Data Haiku<br/><br />NSManagedObjectCon<br/><br />Text just doesn't fit — <a href="http://twitter.com/hatfinch">hatfinch</a><br /><br />its way too complex<br/><br />painful big design upfront<br/><br />I'll Archive instead — <a href="http://twitter.com/alancfrancis">alancfrancis</a><br /><br />Core Data framework<br/><br />You manage object models<br/><br />NSPredicate — <a href="http://twitter.com/adurdin">adurdin</a><br /><br />Core data is fun<br/><br />makes storage easy and fast<br/><br />elastic wombat — <a href="http://twitter.com/greyareauk">GreyAreaUK</a><br /><br /><h3>The Winner!</h3><br /><br />Core Data haiku winners and immortal beings played by Sean Connery share an important characteristic: in the end, there can be only one. And it's <a href="http://twitter.com/adurdin/statuses/8586359895">this one, from adurdin</a>:<br /><br />SELECT * FROM thing<br/><br />WHERE value =… fuck it—<br/><br />just use Core Data.<br /><br />Congratulations! I'll contact the winner via Twitter to send him his prize.Graham Leehttp://www.blogger.com/profile/07305141119009757571noreply@blogger.com0tag:blogger.com,1999:blog-25595390.post-3844592618154488222010-01-10T17:12:00.001+00:002010-01-10T17:12:22.045+00:00Unit testing Core Data-driven apps, fit the secondIt took longer than I expected to follow up <a href="http://iamleeg.blogspot.com/2009/09/unit-testing-core-data-driven-apps.html">my previous article on unit testing and Core Data</a>, but here it is.<br /><br />Note that the pattern presented last time, <em>Remove the Core Data Dependence</em>, is by far my preferred option. If a part of your code doesn't really depend on managed objects and suchlike, it shouldn't need them to be present just because it works with (or in) classes that do. The following pattern is recommended only when you aren't able to abstract away the Core Data-ness of the code under test.<br /><br /><em>Pattern 2: construct an in-memory Core Data stack.</em> The unit test classes you develop ought to have these, seemingly contradictory properties:<br /><br /><ul><li>no dependence on external state: the tests must run the same way every time they run. That means that the environment for each test must be controlled exactly; dependence on "live" application support files, document files or the user defaults are all no-nos.</li><br /><li>close approximation to the application environment: you're interested in how your app runs, not how nice a unit test suite you can create.</li></ul><br /><br />To satisfy both of these properties simultaneously, construct a Core Data stack in the test suite which behaves in the same way but which does not use the persistent store (i.e. document files) used by the real app. My preference is to use the in-memory store type, so that every time it is created it is guaranteed to have no reference to any prior state (unlike a file-backed store type, where you have to rely on unlinking the document files and hoping there are no timing issues in the test framework which might cause two tests simultaneously to use the same file).<br /><br />My test case class interface looks like this (note that this is for a dependent test case bundle that gets embedded into the app; there's an important reason for that which I'll come to later). The managed object context will be needed in the test methods to insert new objects, I don't (yet) need any of the other objects to be visible inside the tests but the same objects must be used in <tt>-setUp</tt> and <tt>-tearDown</tt>.<br /><br /><pre>#import <SenTestingKit/SenTestingKit.h><br /><br />@interface SomeCoreDataTests : SenTestCase {<br /> NSPersistentStoreCoordinator *coord;<br /> NSManagedObjectContext *ctx;<br /> NSManagedObjectModel *model;<br /> NSPersistentStore *store;<br />}<br /><br />@end<br /></pre><br /><br />The environment for the tests is configured thus. I would have all of the error reporting done in tests, rather than that one lone assertion in <tt>-tearDown</tt>, because the SenTest framework doesn't report properly on assertion failures in that method or in <tt>-setUp</tt>. So the <tt>-testThatEnvironmentWorks</tt> test method is a bellwether for the test environment being properly set up, but obviously can't test the results of tear-down because the environment hasn't been torn down when it runs.<br /><br /><pre><br />#import "TuneNeedsHighlightingTests.h"<br /><br />@implementation TuneNeedsHighlightingTests<br /><br />- (void)setUp<br />{<br /> model = [[NSManagedObjectModel mergedModelFromBundles: nil] retain];<br /> NSLog(@"model: %@", model);<br /> coord = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: model];<br /> store = [coord addPersistentStoreWithType: NSInMemoryStoreType<br /> configuration: nil<br /> URL: nil<br /> options: nil <br /> error: NULL];<br /> ctx = [[NSManagedObjectContext alloc] init];<br /> [ctx setPersistentStoreCoordinator: coord];<br />}<br /><br />- (void)tearDown<br />{<br /> [ctx release];<br /> ctx = nil;<br /> NSError *error = nil;<br /> STAssertTrue([coord removePersistentStore: store error: &error], <br /> @"couldn't remove persistent store: %@", error);<br /> store = nil;<br /> [coord release];<br /> coord = nil;<br /> [model release];<br /> model = nil;<br />}<br /><br />- (void)testThatEnvironmentWorks<br />{<br /> STAssertNotNil(store, @"no persistent store");<br />}<br />@end<br /></pre><br /><br />The important part is in setting up the managed object model. In using <tt>[NSManagedObjectModel mergedModelFromBundles: nil]</tt>, we get the managed object model derived from loading all MOMs in the main bundle—remembering that this is an injected test framework, that's the application bundle. In other words the MOM is <em>the same as that created by the app delegate</em>. We get to use the in-memory store as a clean slate every time through, but otherwise the entity definitions and behaviours ought to be identical to those provided by the real app.Graham Leehttp://www.blogger.com/profile/07305141119009757571noreply@blogger.com5tag:blogger.com,1999:blog-25595390.post-28100276535254846192010-01-01T13:15:00.000+00:002010-01-01T13:15:00.259+00:00CocoaHeads Swindon, January and FebruaryThe next CocoaHeads Swindon will take place on 4th January, at the Glue Pot in Swindon. Get here at 8 for some NSChitChat with your (well, my) local Mac developer community.<br /><br />There is <em>no February meeting</em> of Swindon CocoaHeads, on account of <a href="http://www.nsconference.com">NSConference Europe</a> taking place in Reading on that weekend. So buy your NSConference ticket and come along to say hi!Graham Leehttp://www.blogger.com/profile/07305141119009757571noreply@blogger.com0tag:blogger.com,1999:blog-25595390.post-38423405473014184072009-12-29T16:47:00.001+00:002009-12-29T16:47:10.648+00:00Nearly the end-of-year reviewMy first post (Farkers, feel free to <a href="http://www.fark.com/farq/farkisms.shtml#z.22First_Post.22_time_warp">replace that with "boobies"</a>) of the year 2009 was a <a href="http://iamleeg.blogspot.com/2009/01/what-new-in-2009.html">review of 2008's blog</a> and look forward to 2009. It's time to do the same for the 2009/2010 blogyear bifecta.<br /><br /><h3>Let's start with the recap.</h3><br /><br />2009 was a comparatively quiet year for iamleeg, with a total of 45 posts (including this one). Although I gave up on <a href="http://www.livejournal.com">LiveJournal</a>, leading to an amount of "mission creep" in the content of this blog, I think that the vast increase my use of <a href="http://twitter.com/iamleeg">Twitter</a> led to the decline in post frequency here. I've come to use Twitter as a replacement for Usenet, it's much easier to share opinions and discuss things on Twitter where there's more of a balanced conversation and less of iamleeg telling the rest of the world how things should work. The other main contributory factor was that I spend my days writing for a living currently, split between authorship, consultation and the <a href="http://www.mac-developer-network.com/category/columns/security/">MDN security column</a>. I'm often all written out when it comes to the end of the day.<br /><br />So, the mission creep. 2009 saw this blog become more of a home for ideas long enough to warrant a whole page on the internet, losing its tech focus—directly as a result of dropping LJ, which is where non-tech ideas used to end up. However, statistics show that the tech theme is still prevalent, with only four of the posts being about music or dancing. Security has become both the major topic as well as the popular choice; the most-read article was <a href="http://iamleeg.blogspot.com/2009/06/beer-improves-perception-of-security.html">Beer Improves Perception of Security</a>.<br /><br />During August and September the focus started to shift towards independent business and contract work, as indeed <a href="http://iamleeg.blogspot.com/2009/06/going-indie.html">I made that shift</a>. Self-employment is working well for me, the ability to choose where I focus my effort has let me get a number of things done while still retaining a sense of sanity and a balance with my social life.<br /><br /><h3>So what about next year?</h3><br /><br />Well, the fact that I have a number of different things to focus on leads to an important choice: I need to either regroup around some specific area or choose to remain a polymath, but either way I need to be more rigorous about defining the boundaries for different tasks. My major project comes to an end early in 2010, and after that it's time to calm down and take a deep look at what happens next. I have a couple of interesting potential clients lined up, and have put onto the back burner my own application which will definitely see more work. I also have some ideas for personal development which I need to prioritise and get cracking on. The only thing preventing me from moving on a number of different projects is convincing myself I have time for them.<br /><br />So the blog will fit in with that time-management strategy; I won't necessarily decide that 9:00-10:14 on a Monday is always blogging time, but will resolve to put aside some time to writing interesting things. One thing I have found is that working on one thing for a whole day means I don't get much of it done, so factoring that into my plans will let me take advantage of it. Half an hour working on a new article at lunchtime could be the stimulus required to get more out of the afternoon. My weapon of choice for organising my work has always been <a href="http://www.omnigroup.com/applications/omnifocus/">OmniFocus</a>, it's time to be more rigorous about using it. It doesn't actually work well for time allocation, but it <em>does</em> let me see what needs to be done next on the various things I have outstanding.<br /><br />Obviously what becomes the content of this blog depends on what happens after I've shaken down all of those considerations and sorted out what it means to be leeg. Happy new year, and stay tuned to find out what happens.Graham Leehttp://www.blogger.com/profile/07305141119009757571noreply@blogger.com0tag:blogger.com,1999:blog-25595390.post-62731685989362376532009-12-17T11:19:00.001+00:002009-12-17T11:19:02.532+00:00On Operation ChokeholdSo Fake Steve Jobs has <a href="http://www.fakesteve.net/2009/12/operation-chokehold.html">announced Operation Chokehold</a>, a wireless flashmob in which disgruntled AT&T customers are to use data-intensive apps for an hour in protest at the poor service and reduced investment AT&T provide on their network. At time of writing, <a href="http://www.facebook.com/operationchokehold">Operation Chokehold</a> has 3,000 fans on Facebook - a small fraction of the ∼82M AT&T Mobility subscribers in the U.S. Fake Steve has latterly <a href="http://www.fakesteve.net/2009/12/is-operation-chokehold-illegal-or-just-stupid-should-we-do-something-else.html">wondered whether it is illegal</a> (using the "it's now out of my hands" defence, popular with people who don't understand what <a href="http://www.state.gov/s/ct/rls/other/un/65761.htm">incitement</a> means), and seemingly back-pedalled, considering aloud whether people might try a shorter duration or physical flashmob of AT&T stores instead. It would appear that the FCC (the U.S. agency responsible for regulating national and international communications) has weighed in, declaring a wireless flashmob to be <a href="http://abcnews.go.com/Technology/GadgetGuide/fake-steve-jobs-rallies-iphone-users-cripple-att/story?id=9355447&page=1">irresponsible and "a significant public safety concern"</a>.<br /><br />How is it a concern? Due to the way the phones work, you don't need to the capacity to support all of the users, all of the time, in order to provide a reasonable service. Think of running a file-sharing service like DropBox or Humyo. If you offered up to 10GB storage per customer and have 10,000 customers, then you need 100TB of storage, right? Wrong. That's the maximum that could be used, but let's say in practice you find average use to be 100MB/customer. It turns out that 1TB of storage would be the minimum you'd need to satisfy current demand, if you had even 1.5TB then you'd comfortably support the current customer base while allowing for some future use spikes or growth. The question most businesses ask then is not how risky it is to drop below 100% capacity, but how much risk they can accept in their buffer over average capacity. The mobile phone network operates in the same way. To avoid dropped calls you don't need the bandwidth to support 100% of the phones operating 100% of the time, you need to support the average number of phones the average amount of time, plus a little extra for (hopefully foreseen) additional demand.<br /><br /><a href="http://www.retrobrick.com/4500x.html"><img style="margin-left:auto; margin-right:auto; display:block;" src="http://www.retrobrick.com/4500x.jpg"></a><br /><br />The argument by AT&T and the FCC against the wireless flashmob then is that because the network is oversubscribed as an accepted business risk, it would actually be possible for the concerted operation of a large number of users to cause disruption to the network. This eventuality is evinced every year in the early morning of January 1st, as people phone or SMS each other with New Year greetings. People making legitimate calls during this time could be disconnected or unable to place a call at all—while that would undoubtedly make the protest noticed by AT&T it's that aspect of it which makes it a potential public safety concern. Personally, I find it hard to believe that the network doesn't have either dedicated capacity or priority quality of service (QoS) treatment for 9-1-1 calls, but it's possible still that some 9-1-1 calls might not get placed correctly. That's especially true if the caller's handset can't even connect to a tower, which could happen if nearby towers were all saturated with phones making data connections. While it's possible to mitigate that risk (dedicated cell towers for 9-1-1 service, which emergency calls are handed over to) it would be very expensive to implement. There's no business need for AT&T to specially support emergency calls, as they don't make any money from them, so they'd only do that if the FCC mandated it.<br /><br />But then there are all the non-9-1-1 emergency calls—people phoning their local doctor or hospital, and "business critical" calls made by people who somehow think that their business is critical. Even the day-to-day running of government is at least partially conducted over the regular phone networks, as was seen when the pager traffic from New York on September 11th 2001 got posted to WikiLeaks. These calls are all lumped in with the regular calls, because they <em>are</em> regular calls. The only way to mitigate the risk of dropping these is to increase the capacity of the network, which is exactly the thing that people are saying AT&T don't do to a satisfactory level. If the contracts on AT&T Mobility are anything like the contracts on UK phone networks, then subscribers don't have a service level agreement (SLA) with the provider, so there's no guarantee of provision. The sticking point is the level of <em>expected</em> provision doesn't match that. If the providers operated multi-tier subscription services like the broadband providers do in the UK, then they probably would do QoS management so that preferential customers get better call service—again, assuming the customers can connect to the cell tower in the first place. But again, that's a business issue, and if the guy participating in Chokehold has a more expensive plan than the girl trying to phone the hospital, his connection will win.<br /><br />Will Chokehold fulfil its goal of making AT&T invest more in its infrastructure? I don't know. Will it actually disrupt public safety services such as 9-1-1? I doubt it. Is it a scale model for a terrorist attack on the communications infrastructure of the US? Certainly not. Much easier to <a href="http://john-savageau.com/2009/10/12/telecom-risk-and-security-part-2-%e2%80%93-the-carrier-hotel-supernode/">jump down a manhole</a> and snip the cables to the data centres.Graham Leehttp://www.blogger.com/profile/07305141119009757571noreply@blogger.com0tag:blogger.com,1999:blog-25595390.post-37436036207685106472009-12-15T17:42:00.002+00:002009-12-31T14:01:25.167+00:00Consulting versus micro-ISV development<a href="http://kosmaczewski.net/2009/12/15/reflexions-on-the-software-business/">Reflexions on the software business</a> really is an interesting read. Let me borrow Adrian's summary of his own post:<br /><br /><blockquote>Now, here’s an insider tip: if your objective is living a nightmare, tearing yourself apart and swear never touching a keyboard again, choose [consulting]. If your objective is enjoying a healthy life, making money and living long and prosper, choose [your own products].</blockquote><br /><br />As the author himself allows, the arguments presented either way are grossly oversimplified. In fact I think there is a very simple axiom underlying what he says, which if untrue moves the balance away from writing your own products and into consulting, contracting or even salaried work. Let me start by introducing some features missed out of the original article. They may, depending on your point of view, be pros or cons. They may also apply to more than one of the roles.<br /><br /><h3>A consultant:</h3><br /><ul><li>builds up relationships with many people and organisations</li><br /><li>is constantly learning</li><br /><li>works on numerous different products</li><br /><li>is often the saviour of projects and businesses</li><br /><li>gets to choose what the next project is</li><br /><li>has had the risks identified and managed by his client</li><br /><li>can focus on two things: writing software, and convincing people to pay him to write software</li><br /><li>renegotiates when the client's requirements change</ul><br /><br /><h3>A μISV developer:</h3><br /><ul><li>is in sales, marketing, support, product management, engineering, testing, graphics, legal, finance, IT and HR until she can afford to outsource or employ</li><br /><li>has no income until version 1.0 is out</li><br /><li>cannot choose when to put down the next version to work on the next product</li><br /><li>can work on nothing else</li><br /><li>works largely alone</li><br /><li>must constantly find new ways to sell the same few products</li><br /><li>must pay for her own training and development</li></ul><br /><br /><h3>A salaried developer:</h3><br /><ul><li>may only work on what the managers want</li><br /><li>has a legal minimum level of security</li><br /><li>can rely on a number of other people to help out</li><br /><li>can look to other staff to do tasks unrelated to his mission</li><br /><li>gets paid holiday, sick and parental leave</li><br /><li>can agree a personal development plan with the highers-up</li><br /><li>owns none of the work he creates</li></ul><br /><br />I think the axiom underpinning Adrian Kosmaczewski's article is: <q>happiness ∝ creative freedom</q>. Does that apply to you? Take the list of things I've defined above, and the list of things in the original article, and put them not into "μISV vs. consultant" but "excited vs. anxious vs. apathetic". Now, this is more likely to say something about your personality than about whether one job is better than another. Do you enjoy risks? Would you accept a bigger risk in order to get more freedom? More money? Would you trade the other way? Do you see each non-software-developing activity as necessary, fun, an imposition, or something else?<br /><br />So thankyou, Adrian, for making me think, and for setting out some of the stalls of two potential careers in software. Unfortunately I don't think your conclusion is as true as you do.Graham Leehttp://www.blogger.com/profile/07305141119009757571noreply@blogger.com5tag:blogger.com,1999:blog-25595390.post-29514420441084673352009-11-01T14:48:00.001+00:002009-11-01T14:48:16.071+00:00Poke the other one, it's got bells onOriginally the title for this post was to be "Why a Morris organisation should adopt social media (and why they probably won't)", with what is now the title being reduced to the rank of a subtitle. Then I remembered that I am leeg, and as such humour is always better than content (certainly a lot easier). So we have the title you see before you.<br /><br />Please bear in mind when reading the epistle located below that I'm fairly new to the whole world of Morris, and especially new to its political fiddle-faddle. If anything here seems to stereotype people or their motives, it's based on the experience of someone who can at best be considered an informed outsider. [And for those who are even more of an outsider than I am, Morris dancing is the name for a roughly-related collection of traditional English dancing styles, performed by groups called sides or teams. It's both good fun and a decent workout, give it a go.]<br /><br />It seems to have been a problem for at least the length of my lifetime that Morris lacks any relevance to what, for sake of pomposity, I shall refer to as the man on the Clapham omnibus — taking the irony fully on board. That your average person sees no reason to engage with or appreciate the Morris. Why? Has the Morris really made much of an attempt to engage with or appreciate the life of the average person? Not, I would argue, at any concerted or large-scale level, leaving the final impression most people have of Morris dancers the same as their first impression: a bunch of old men in silly clothes hitting each other with sticks.<br /><br />So, shouldn't I have mentioned the social media by now? Yes, I'm just coming to that, it's only a couple of paragraphs away now. First some context. There are three umbrella organisations for the Morris in the UK: the <a href="http://www.themorrisring.org/">Morris Ring</a> is the oldest, with its infamous men-only rules; the <a href="http://www.morrisfed.org.uk/">Morris Federation</a> (whose website was broken at time of writing) started life as the less-infamously women-only Women's Morris Federation; then there's <a href="http://www.open-morris.org/">Open Morris</a>, which to my knowledge has never had any infamous membership rules and is the youngest of the three organisations. None of these organisations takes on a promotional or advocacy rôle — or at least, if they do, they've done a bad job of it. They represent more of an internal support network, offering guidance, information, training and the like to the sides. If you don't believe that they aren't promotional bodies, take a look at their websites.<br /><br />As a digression I will use this paragraph to mention the <a href="http://www.efdss.org/">English Folk Dance and Song Society</a>, which does indeed have advocacy, promotion and outreach as its goals. However, I'm not aware what the relationship between the EFDSS and any of the sides or morris umbrella groups is. That's definitely lack of knowledge on my part, rather than indicative of a lack of interaction. Certainly the three groups named above have all contributed to the EFDSS's magazine, ED&S, recently, although I haven't read their contributions. There's a lot of morris-related material in the EFDSS archives, too. By the way, I'm reliably informed that the society's name is pronounced "EFdəs".<br /><br />There are, then, four groups identified who either do, or could take on if they so chose, a rôle in promoting the morris to the general public. Given the continued and increasing popularity that web-based media, particularly social media, has in the world, let's examine the part each of these groups plays.<br /><br /><ul><li>Twitter Presences: 0.</li><br /><li>Official Facebook Presences: 2. The EFDSS has a fan page. There's a group for Open Morris too, which looks like it could be run by the real organisation. I think that counts as user-generated content is part of the world of social media.</li><br /><li>Official YouTube Channels: 0. Or at least none that I could find.</li><br /><li>Myspace Presences: 1. EFDSS again.</li><br /><li>Podcasts: 0.</li><br /><li>RSS feeds (that scraping noise you hear, it's the bottom of the barrel): 1. It's the Morris Ring's news feed. I nearly fell out of my chair.</li><br /><li>For completeness, I'll also mention that there's an unofficial mailing list called MDDL (Morris Dancing Discussion List) which is very active with a strong signal-to-noise ratio.</li><br /></ul><br /><br />Now, why should any of this be important? Well, as you're reading this, you're consuming a blog. You either thought "I would like to know what leeg is up to, I'll read his blog", "I heard that some guy on the interwebs really lays into morris dancing organisations, I'll check it out", or something else which made you decide to spend time engaging with social media and user-generated content on the web. That's time which the various morris groups could have spent <em>injecting your brain with Morris Dancing</em>. Are they doing that? No. They're writing internal newsletters bemoaning the lack of traditional dancing in the national curriculum, and press releases for the Torygraph to pick up, claiming that morris dancing is dying out because all of the practitioners are getting too old. In fact, it's been nearly a year since that last one was done.<br /><br />The problem is that you and I and everybody else don't give a shit about the Morris Ring Circular or their press releases, in the same way we give a shit about, say, procrastinating on YouTube, following interesting people on Twitter, catching up with friends on Facebook and so on. The people who complain about morris dancing fading into irrelevance are even managing to <em>complain about it in an irrelevant fashion</em>. Irony. They're doing it right.<br /><br />And the most galling thing is that the social media and traditional dancing <em>could</em> go together so well. Take a photo like <a href="http://www.morris1830.org.uk/photos/?p=1418">this, which I took at the Morris 18-30 in WakeField</a>:<br /><br /><img src="http://www.morris1830.org.uk/photos/_images/dbDeliver.aspx?id=1418&type=webFull"><br /><br />You may wonder why everyone's wearing different costumes; well the answer is that they're from different sides. A mash-up could tag the dancers with their side's name, and a link to their website. Your next question would, of course, be the same as mine: "but where the hell <em>is</em> Packington, anyway?" A map showing the location of each side could be available, perhaps even showing proximity of their practice venue to your current location and when they'll next be practising (please, do not get me started on the existing SideFinder pages. You would not like what I would become). Had I remembered what dance was being danced (I think it's Skirmishes, though I'm sure someone would be able to spot it from the photo), then information about that dance and videos of sides performing it could be available.<br /><br />[Another aside: the relative obscurity of some teams' locations has consequences for those teams' performances. As an example, the fool of Adderbury Morris always wears a hat made of fox skin during the dances. This is because when the first team was formed, the fool went home to tell his wife about his new position. Her response is recorded as being "Adderbury? Wear the fox hat".]<br /><br />"Aha," you hypothetically cry. "But I would not have seen the photo in the first place, had you not talked about it on your blog." Indeed no, but the point of blogs, Twitter, Tumblr and the like is that you get personal recommendations from people you either trust or consider expert in their field. So I think it's fair to have introduced the photo in that way; and that there's a space online for personal recommendation of trying out morris dancing. And that there ought to be some organisation helping people to do that promotion.<br /><br />Incidentally, the <a href="http://www.morris1830.org.uk">Morris 18-30</a> is actually a good example of a group (or phenomenon, I suppose) building a decent website with good amounts of information, and providing an easy way for people to get their photos online. There are many sides which have done the same; <a href="http://www.youtube.com/user/westminstermorrismen">Westminster Morris Men's YouTube channel</a> has a decent set of videos including some from the archives. My point is not that this information is not being made available, nor that an effort is not being made — I chose the 18-30 photo for my example because I took the picture and have the right to re-use it in this blog.<br /><br />I don't think that the fact some sides do well at promoting themselves affects my argument; those who don't have the skills or resources to do this work themselves are not being helped by the national/international bodies. People who might be interested in traditional dancing aren't finding out about it, because the nearest side who have any skill at marketing are in the next county. In a world where information can travel the world in a fraction of a second, that's ludicrous.<br /><br />So the fact that 18-30 has a good website where people can share information easily is a good thing. The various mash-up suggestions I made would all be good improvements, and were they implemented by an umbrella group then everyone could take advantage of them. My point is that the umbrella organisations should be taking and collating the vast amount of morris-related information out there, and making it easy for people who are not (yet) in the morris to find. They should be using it to promote the dance form and the social activities that surround it, but they aren't. They should be providing a central service to make it easier for sides to share their own material, but they aren't. They should be taking their existing archives and making them available online, but they aren't. They should be looking at the innovations made by some of their members and applying them at the international level, but aren't.<br /><br />In addition to existing content, there is plenty of scope for promotional material based on novel content distributed over the internet. The dances, music and even pub sessions could make great segments for a vlog or video podcast. Even mini-instructionals could be presented as video podcasts or on a YouTube channel, so that people can try things out without having to join a side first. "What's the point of dancing a team dance on your own?" — leaving jigs aside as PhD-level morris, some people may just want to find out whether they can do some of the basic stuff on their own before turning up to a practice session. If you're not sure whether you want to take part in an activity, would you have your first try in front of twenty people who've been doing it for years, and are each armed with a big stick? Maybe not.<br /><br />So there's plenty of space for morris information to be distributed digitally. But, really, who gives a toss? That's where the promotional aspect comes in. I've already mentioned the personal level of promotion through Twitter and the like. There are obvious places where morris could be promoted; what's on guides, tourism sites, tradition-reporting sites and the like. But how about novel audiences? Dancers, like many British people, enjoy a <a href="http://www.beerintheevening.com/">Beer in the Evening</a>. Given decent information feeds like the things I described a few paragraphs ago, morris data could be highly <a href="http://mashable.com/">Mashable</a>, featuring in those little <a href="http://www.facebook.com">Facebook</a> games. If people like what they see, they will <a href="http://digg.com">Digg</a> it. Were one of the umbrella orgs to hire a dashing, intelligent, handsome developer-dancer they could even promote through the <a href="http://www.apple.com/iphone/apps-for-iphone/">iPhone app store</a> (though where would they <a href="http://www.thaesofereode.info/contact.shtml">find such a person?</a>).<br /><br />And what Americans like to call "the kicker" is this: <em>real people drink beer, use websites and download apps</em>. Most of the dancers I've met are either from families of dancers or already had interest in folk music; in that sense the person on the street is an "unexploited vertical" for the marketers of morris, and probably has been since the end of the first world war.<br /><br />OK, so that's what could be done, who should be doing it, and why. Is it fair for me to put words in the mouths of the umbrella orgs in suggesting why they aren't currently doing it? No, but I will anyway. If you think this blog is fair, then I've got a slightly-used iBook I'll sell you for a great price.<br /><br />I think that for a large part, the people in charge probably just don't use and therefore don't understand the potential of social media. But that doesn't explain why the morris umbrella organisations don't do <em>any promotion whatsoever</em>. At least one of the organisations may be wary of getting too much publicity for themselves; I'm not a lawyer of course, but the <a href="http://services.parliament.uk/bills/2008-09/equality.html">equality bill</a> currently awaiting its 3rd reading in the House of Commons could require the Morris Ring to change its membership rules, as it "Extends discrimination protection in the terms of membership and benefits for private clubs and associations". I expect there isn't much in the way of training available to the organisations in the general field of marketing. I'm not sure what kind of budgets these groups run on, but maybe the three of them together could afford a part-time marketer.<br /><br />Of course, there's some appeal to the idea that you're in a secret society, isn't there? It's quite exciting to think that you do something enjoyed by few others, and it's easier to become important in smaller social groups. Not that I'm suggesting that's a related point, oh no.<br /><br />I apologise for writing such a long post. I didn't have the time to write a shorter one.Graham Leehttp://www.blogger.com/profile/07305141119009757571noreply@blogger.com3tag:blogger.com,1999:blog-25595390.post-46821438954613693042009-09-25T00:36:00.001+01:002009-09-25T00:36:14.573+01:00Unfamiliar territoryPeople who've seen me play music more than once will probably have noticed more than a slight sense of a pattern - give me a fiddle (or if you're really unlucky then I'll bring my own), and I play English folk music. Give me a guitar and I'll play rock and roll. That's just what my fingers are used to - to me the guitar has six strings of rockabilly and the fiddle has four strings of constant billy. No, I didn't write this piece just to get that pun in, though I am glad that I did. I can now go to my grave a happy man, safe in the knowledge that I have compared fishes flying over mountains with blues-derived country music. Classy.<br /><br />Well, I think it's time to change things around a bit. I want to leave my violin all shook up, and my guitar all in a garden green. It probably sounds quite easy, given that I already know all the tunes, and just want to play them on different instruments, but really it isn't. There are two important issues which make it hard for me to just swap over.<br /><br />The first is that in many cases I don't actually know the tune at all, I just use muscle memory to get my digits moving in the right places for music to occur. That's particularly true in the case of rock n roll music, where there really aren't tunes at all. There are just 'licks', basic one or two bar figures which are strung together into a twelve bar part. But it's also true in folk music which has a similarly hypnotic repetition but with longer figures. So taking a tune to a new instrument means discovering what it is I'm actually playing on the first instrument, then trying to reproduce that on the second.<br /><br />The second issue is that just playing the notes from one instrument on another isn't necessarily the correct thing to do, nor even particularly easy. For a start guitar strings are tuned to fourths (mainly) while violin strings are to fifths, and as the bridges are different shapes the instruments invite playing a different number of strings simultaneously. So what I need to do is not even to work out how to play the same tune on the other instrument, but what that instrument's version of the tune should be and how to play that.<br /><br />I expect that the outcome of this little experiment will be mainly a cacophony, but with some increased understanding of what the instruments can do and how to play them. If I focus on cacophony then I'll probably get quick results, though.Graham Leehttp://www.blogger.com/profile/07305141119009757571noreply@blogger.com1tag:blogger.com,1999:blog-25595390.post-37468537706779718172009-09-18T09:21:00.002+01:002009-09-18T09:48:40.569+01:00Next Swindon CocoaHeads meetingAt one time a quiet market town with no greater claim than to break up the journey between Oxford and Bristol, Swindon is now a bustling hub of Mac and iPhone development activity. The coming meeting of CocoaHeads, at the Glue Pot pub near the train station on Monday October 5th, is a focus of the thriving industry.<br /><br />I really believe that this coming meeting will be a great one for those of you who've never been to a CocoaHeads meeting before. We will be having a roundtable discussion on indie software development and running your own micro-ISV. Whether you are a seasoned indie or just contemplating making the jump and what to find out what's what, come along to the meeting. Share your anecdotes or questions with a group of like-minded developers and discover how one person can design, develop and market their applications.<br /><br />You don't need to register beforehand and there's no door charge, just turn up and talk Cocoa. If you do want to discuss anything with other Swindon CocoaHeads, please <a href="http://lists.mac-developer-network.com/listinfo/cocoaheads-swindon">subscribe to the mailing list</a>.Graham Leehttp://www.blogger.com/profile/07305141119009757571noreply@blogger.com0tag:blogger.com,1999:blog-25595390.post-39973062684099747882009-09-06T15:36:00.001+01:002009-09-06T15:36:16.055+01:00Unit testing Core Data-driven appsNeedless to say, I'm standing on the shoulders of giants here. Chris Hanson <a href="http://chanson.livejournal.com/115621.html">has written a great post</a> on setting up the Core Data "stack" inside unit tests, Bill Bumgarner has written about their experiences <a href="http://www.friday.com/bbum/2005/09/24/unit-testing/">unit-testing Core Data itself</a> and PlayTank have an article about <a href="http://playtank.com/node/9">introspecting the object tree in a managed object model</a>. I'm not going to rehash any of that, though I will touch on bits and pieces.<br /><br />In this post, I'm going to look at one of the patterns I've employed to create testable code in a Core Data application. I'm pretty sure that none of these patterns I'll be discussing is novel, however this series has the usual dual-purpose intention of maybe helping out other developers hoping to improve the coverage of the unit tests in their Core Data apps, and certainly helping me out later when I've forgotten what I did and why ;-).<br /><br /><em>Pattern 1: remove the Core Data dependence.</em> Taking the usual example of a Human Resources application, the code which determines the highest salary in any department cares about employees and their salaries. It does <em>not</em> care about <tt>NSManagedObject</tt> instances and their values for keys. So stop referring to them! Assuming the following initial, hypothetical code:<br /><br /><pre>- (NSInteger)highestSalaryOfEmployees: (NSSet *)employees {<br /> NSInteger highestSalary = -1;<br /> for (NSManagedObject *employee in employees) {<br /> NSInteger thisSalary = [[employee valueForKey: @"salary"] integerValue];<br /> if (thisSalary > highestSalary) highestSalary = thisSalary;<br /> }<br /> //note that if the set's empty, I'll return -1<br /> return highestSalary;<br />}<br /></pre><br /><br />This is how this pattern works:<br /><br /><ol><li><em>Create NSManagedObject subclasses for the entities.</em><br /><pre>@interface GLEmployee : NSManagedObject<br />{}<br />@property (nonatomic, retain) NSString *name;<br />@property (nonatomic, retain) NSNumber *salary;<br />@property (nonatomic, retain) GLDepartment *department;<br />@end<br /></pre><br />This step allows us to see that employees are objects (well, they are in many companies anyway) with a set of attributes. Additionally it allows us to use the compile-time checking for properties with the dot syntax, which isn't available in KVC where we can use any old nonsense as they key name. So go ahead and do that!<br /><pre>- (NSInteger)highestSalaryOfEmployees: (NSSet *)employees {<br /> NSInteger highestSalary = -1;<br /> for (GLEmployee *employee in employees) {<br /> NSInteger thisSalary = [employee.salary integerValue];<br /> if (thisSalary > highestSalary) highestSalary = thisSalary;<br /> }<br /> //note that if the set's empty, I'll return -1<br /> return highestSalary;<br />}<br /></pre><br /></li><br /><li><em>Abstract out the interface to a protocol.</em><br /><pre>@protocol GLEmployeeInterface <NSObject><br />@property (nonatomic, retain) NSNumber *salary;<br />@end<br /></pre><br />Note that I've only added the salary to the protocol definition, as that's the only property used by the code under test and the principle of <a href="http://c2.com/cgi-bin/wiki?YouArentGonnaNeedIt">YAGNI</a> tells us not to add the other properties (yet). The protocol extends the <tt>NSObject</tt> protocol as a safety measure; lots of code expects objects which are subclasses of <tt>NSObject</tt> or adopt the protocol. And the corresponding change to the class definition:<br /><pre>@interface GLEmployee : NSManagedObject <GLEmployeeInterface><br />{}<br />...<br />@end<br /></pre><br />Now our code can depend on that interface instead of a particular class:<br /><pre>- (NSInteger)highestSalaryOfEmployees: (NSSet *)employees {<br /> NSInteger highestSalary = -1;<br /> for (id <GLEmployeeInterface> employee in employees) {<br /> NSInteger thisSalary = [employee.salary integerValue];<br /> if (thisSalary > highestSalary) highestSalary = thisSalary;<br /> }<br /> //note that if the set's empty, I'll return -1<br /> return highestSalary;<br />}<br /></pre><br /></li><br /><li><em>Create a non-Core Data "mock" employee</em><br />Again, YAGNI tells us not to add anything which isn't going to be used.<br /><pre>@interface GLMockEmployee : NSObject <GLEmployeeInterface><br />{<br /> NSNumber *salary;<br />}<br />@property (nonatomic, retain) NSNumber *salary;<br />@end<br /><br />@implementation MockEmployee<br />@synthesize salary;<br />@end<br /></pre><br />Note that because I refactored the code under test to handle classes which conform to the <tt>GLEmployeeInterface</tt> protocol rather than any particular class, this mock employee object is just as good as the Core Data entity as far as that method is concerned, so you can write tests using that mock class without needing to rely on a Core Data stack in the test driver. You've also separated the logic ("I want to know what the highest salary is") from the implementation of the model (Core Data).<br /></li><br /></ol><br /><br />OK, so now that you've written a bunch of tests to exercise that logic, it's time to safely refactor that <tt>for(in)</tt> loop to an exciting block implementation :-).Graham Leehttp://www.blogger.com/profile/07305141119009757571noreply@blogger.com2tag:blogger.com,1999:blog-25595390.post-17650193350301411812009-09-05T09:53:00.001+01:002009-09-05T09:53:53.653+01:00CocoaHeads Swindon is this Monday!The town of Swindon in the Kingsbridge hundred, Wiltshire is famous for two things. The first is the Wilts and Berks Canal, linking the Kennet and Avon at Trowbridge with the Thames at Abingdon. Authorised by act of parliament in 1775, the canal first passed through the town in 1804 and allowed an explosion in both the industrial and residential capacity of the hitherto quiet market cheaping.<br /><br />The second is, of course, the local CocoaHeads chapter. Founded by act of Scotty in 2007, Swindon CocoaHeads quickly brought about a revolution in the teaching and discussion of Mac and iPhone development in the South-West, its influence being felt as far away as Swansea to the West and London to the East. Unlike the W&B canal, Swindon CocoaHeads is still thriving to this day. On Monday, 7th September at 20:00 there will be another of the chapter's monthly meetings, in the Glue Pot pub near the train station. Here, Pieter Omvlee will be leading a talk on ImageKit, and the usual combination of beer and Cocoa chat will also be on show. As always, the <a href="http://cocoaheads.org/uk/Swindon/index.html">CocoaHeads website</a> contains the details.Graham Leehttp://www.blogger.com/profile/07305141119009757571noreply@blogger.com0tag:blogger.com,1999:blog-25595390.post-13822902942804848902009-08-27T00:44:00.001+01:002009-08-27T00:44:53.835+01:00Indie app milestones part oneIn the precious and scarce spare time I have around my regular contracting endeavours, I've been working on my first indie app. It reached an important stage in development today; the first time where I could show somebody who doesn't know what I'm up to the UI and <em>they instinctively knew what the app was for</em>. That's not to say that the app is all shiny and delicious; it's entirely fabricated from standard controls. Standard controls I (personally) don't mind so much. However the GUI will need quite a bit more work before the app is at its most intuitive and before I post any teaser screenshots. Still, let's see how I got here.<br /><br />The app is very much a "scratching my own itch" endeavour. I tooled around with a few ideas for apps while sat in a coffee shop, but one of them jumped out as something I'd use frequently. If I'll use it, then hopefully somebody else will!<br /><br />So I know what this app <em>is</em>, but what does it <em>do</em>? Something I'd bumped into before in software engineering was the concept of a <a href="http://www.c2.com/cgi/wiki?UserStory">User Story</a>: a testable, brief description of something which will add value to the app. I broke out the index cards and wrote a single sentence on each, describing something the user will be able to do once the user story is added to the app. I've got no idea whether I have been complete, exhaustive or accurate in defining these user stories. If I need to change, add or remove any user stories I can easily do that when I decide that it's necessary. I don't need to know now a complete roadmap of the application for the next five years.<br /><br />As an aside, people working on larger teams than my one-man affair may need to estimate how much effort will be needed on their projects and track progress against their estimates. User stories are great for this, because each is small enough to make real progress on in short time, each represents a discrete and (preferably) independent useful addition to the app and so the app is ready to ship any time an integer number of these user stories is complete on a branch. All of this means that it shouldn't be too hard to get the estimate for a user story roughly correct (unlike big up-front planning, which I don't think I've ever seen succeed), that previous complete user stories can help improve estimates on future stories and that even an error of +/- a few stories means you've got something of value to give to the customer.<br /><br />So, back with me, and I've written down an important number of user stories; the number I thought of before I gave up :-). If there are any more they obviously don't jump out at me as a potential user, so I should find them when other people start looking at the app or as I continue using/testing the thing. I eventually came up with 17 user stories, of which 3 are not directly related to the goal of the app ("the user can purchase the app" being one of them). That's a lot of user stories!<br /><br />If anything it's too many stories. If I developed all of those before I shipped, then I'd spend lots of time on niche features before even finding out how useful the real world finds the basic things. I split the stories into two piles; the ones which are absolutely necessary for a <em>preview</em> release, and the ones which can come later. I don't yet care how late "later" is; they could be in 1.0, a point release or a paid upgrade. As I haven't even got to the first beta yet that's immaterial, I just know that they don't need to be now. There are four stories that do need to be now.<br /><br />So, I've started implementing these stories. For the first one I went to a small whiteboard and sketched UI mock-ups. In fact, I came up with four. I then set about finding out whether other apps have similar UI and how they've presented it, to choose one of these mock-ups. Following advice from <a href="http://www.mac-developer-network.com/shows/podcasts/mdnshow/mdn006/">the world according to Gemmell</a> I took photos of the whiteboard at each important stage to act as a design log - I'm also keeping screenshots of the app as I go. Then it's over to Xcode!<br /><br />So a few iterations of whiteboard/Interface Builder/Xcode later and I have two of my four "must-have" stories completed, and already somebody who has seen the app knows what it's about. With any luck (and the next time I snatch any spare time) it won't take long to have the four stories complete, at which point I can start the private beta to find out where to go next. Oh, and what is the app? I'll tell you soon...Graham Leehttp://www.blogger.com/profile/07305141119009757571noreply@blogger.com2tag:blogger.com,1999:blog-25595390.post-71468374984462760562009-08-17T23:54:00.001+01:002009-08-17T23:54:47.559+01:00On XP modeThis is a reply to <a href="https://twitter.com/gcluley/statuses/3370036656">@gcluley</a>, who linked to <a href="http://blogs.zdnet.com/hardware/?p=5197">this ZDNet story</a> (which in turn took its quotes from <a href="http://www.sophos.com/security/podcasts/">Sophos Podcasts</a>).<br /><br />The second most crazy thing about the entire "XP mode" issue in Windows 7 is that the feature is entirely unnecessary. Corporate customers of Windows are already, for the most part, comfortable with managing virtual Windows desktops through third-party products with much better management options or at least have trialled such products. Home users of Windows just take whichever version is pre-installed when they buy the PC and if it means buying new versions of some apps, that's what they do. They're used to it. The group of people who could benefit from XP mode - people with a strong need for app compatibility with XP but with no experience of virtualisation - just doesn't exist.<br /><br />The very existence of the XP mode feature is a microcosmic example of the way Ballmer has been running Microsoft - if there's a market out there that MS isn't in, MS needs to be in it pronto. Bing, Morro, Web-Office, Zune and now virtualisation are all testament to the inability of Microsoft to concentrate on what it does. What Microsoft really does is to sell two things; an enterprise computing environment and an OEM software distribution. Forget that Windows and Office are accounted as two separate products; MS sell Windows+Office to businesses and Windows to computer makers.<br /><br />Now the interesting question to ponder is which of Microsoft's (real or perceived; remember they aren't necessarily <em>in</em> this market) competitors the "XP mode" feature is a response to. My interpretation is that it's not actually VMware and its ilk at all - Microsoft is once again responding to nonexistent competition from Apple. Boot Camp and the third-party desktop virtualisation offerings on the Mac (including, without hint of irony, VMware) let users use OS X as their shiny new OS with an "XP mode" of sorts for legacy applications. I think what Microsoft are trying to do here is to show that Windows can be the new shiny with XP as the legacy mode, and are therefore positioning XP mode as a counter to the fictitious competition from Apple. Oh, and if you don't believe me when I say that the competition from Apple doesn't exist - <a href="http://techblips.dailyradar.com/story/apple_owns_91_share_of_the_premium_computer_market/">Apple sell all of the premium computers</a> while Microsoft take the aforementioned corporate and OEM markets.<br /><br />OK, so if that was the second most crazy thing about XP mode, what is the most crazy thing about XP mode? It's also that the feature shouldn't exist. Windows has always had a problem with segregating distinct services which <a href="http://en.wikipedia.org/wiki/FreeBSD_jail">other</a> <a href="http://www.sun.com/bigadmin/content/zones/index.jsp">operating</a> <a href="http://www.redbooks.ibm.com/Redbooks.nsf/RedbookAbstracts/sg247039.html?OpenDocument">systems</a> don't suffer from. While Microsoft's avoidance of this issue has allowed a whole new software industry to spring up around it, the fact that they need to start a <em>second</em> copy of Windows just to get some applications running in Windows 7 doesn't give me much hope for the future.Graham Leehttp://www.blogger.com/profile/07305141119009757571noreply@blogger.com2tag:blogger.com,1999:blog-25595390.post-66709829529819454702009-08-14T18:53:00.001+01:002009-08-14T18:53:46.170+01:00The next million-dollar iPhone applicationI'm constantly surprised by questions <a href="http://stackoverflow.com/questions/1279185/what-are-my-iphone-sdk-development-setup-options">such as this one</a>. They invariably go along the lines:<br /><br /><blockquote>I heard that I need to get a Mac to do iPhone development. I want to do iPhone development but do I have to buy a Mac? Is there any other way to develop iPhone software?</blockquote><br /><br />If the projected sales for your app don't meet the cost of a new computer, whatever platform you're developing on, <em>it's time to get a different idea for your app</em>. I speak with the smug self-confidence of one who has yet to get his own app within smelling distance of the store.Graham Leehttp://www.blogger.com/profile/07305141119009757571noreply@blogger.com4tag:blogger.com,1999:blog-25595390.post-15384982035742758662009-08-13T09:20:00.001+01:002009-08-13T09:20:50.722+01:00A rap upon the nogginWhen a patient may be concussed, it's common for parademics to ask simple, topical questions to determine whether the patient is confused. Questions such as "who is the Prime Minister"?<br /><br />I think somebody may have knocked this poor spammer upside the head (emphasis is mine):<br /><br /><blockquote>Lloyd's TSB Group plc<br />25 Gresham Street<br />London EC2V 7HN<br /><br />Greetings,<br /><br />Following the recent announcement by the Chancellor of the Exchequer, <em>Gordon Brown</em> that all assets in accounts that have been <br /><br />dormant for over 15years be transferred to the Treasury i send this mail to you.<br /><br />There is a dormant account in my office,with no owner or beneficiaries. It will be in my interest to transfer this assets <br /><br />worth 20,000,000 British pounds to an offshore country. If you can be a collaborator/partner to this please indicate interest <br /><br />immediately for us to proceed.<br /><br />Remember this is absolutely confidential,as i am seeking your assistance to act as the beneficiary of the account, since we <br /><br />are not allowed to operate a foreign accounts. Your contact phone numbers and name will be necessary for this effect.<br />I have reposed my confidence in you and hope that you will not disappoint me.<br /><br />My Regards,<br />Jim McConville<br />Lloyd's TSB Group plc</blockquote>Graham Leehttp://www.blogger.com/profile/07305141119009757571noreply@blogger.com1tag:blogger.com,1999:blog-25595390.post-41352370253403263192009-07-31T19:52:00.001+01:002009-07-31T21:02:01.990+01:00Website relaunch!Today I have re-launched <a href="http://thaesofereode.info/">Thaes Ofereode</a> to focus on my new role as an independent Mac boffin. I really like the new design, which was created by the ever-delightful <a href="http://sessrumnir.wikidot.com">Freya</a>.<br /><br /><b><em>edit</em></b>: Gecko doesn't understand the CSS media selector I was using to provide the iPhone CSS. I've therefore reverted the iPhone design until I can find a way to get Firefox to suck less.<br /><br /><img src="http://thaesofereode.info/images/iphone1.png" align="left" width="25%"><br />The one thing I added to her design was a more iPhone-friendly look. For those of you without iPhones, the screenshots demonstrate how the mobile version will appear. For those of you who are CSS experts, the following will probably be rather dull but for those like me who know enough to be dangerous but no more, here's how it's done.<br /><br />The three-column layout works really well on the desktop, but the iPhone has a tallscreen-oriented display so not much space for horizontal layout. I therefore chose to put the leftmost, menu column <em>underneath</em> the main content on each page, so iPhone users get to see the heading and then the meat and potatoes. If they are interested enough to get to the end, they'll see the links to the rest of the site.<img src="http://thaesofereode.info/images/iphone2.png" align="right" width="25%"><br /><br />The links, btw, are just paragraphs with a border, a lot of padding and the magic <tt><a href="http://www.css3.info/preview/rounded-border/">-webkit-border-radius</a></tt> providing the roundy edges; no messing with JavaScript and funny part-circle images.<br /><br />So, the third column? Well those impressive-looking widgets can't be displayed on the phone anyway, and would be a bit out of place so they're gone for the moment with the mobile CSS. I may code up some JavaScript replacements soon enough, but I'll need to find somewhere else for them to go. In the meantime, I know you read my blog because you're here, and there are many apps which can help you <a href="http://twitter.com/iamleeg">follow me on Twitter</a>.Graham Leehttp://www.blogger.com/profile/07305141119009757571noreply@blogger.com0tag:blogger.com,1999:blog-25595390.post-60359752631903844952009-07-28T23:01:00.001+01:002009-07-28T23:01:08.283+01:00Next CocoaHeads Swindon meet!So for those of you who didn't manage to enjoy the glories to be found in the town that was the inspiration for <a href="http://scripturetext.com/luke/8-32.htm">one of Legion's more colourful adventures</a>,[*] next Monday, the 3rd of August, offers yet another once-in-a-monthtime opportunity! As ever, the location is in (or just outside) the Glue Pot, a strong man's stone's throw from the Swindon train station. This month's meeting is a recap on QTKit, to allow those who weren't there last time due to the reschedule to catch up on integrating QuickTime into their Cocoa apps.<br /><br />[*] What am I doing knowing quotes like that? Well, the clue is in the user name. When I was a student my UNIX username was <tt>leeg</tt>, clearly based on my real name. In short order, I was introduced as "He is Leeg, for he are many" and thus <tt>iamleeg</tt>.Graham Leehttp://www.blogger.com/profile/07305141119009757571noreply@blogger.com0