Archive for 2012

Page 1 of 3

    Managing Sub-Modules with Git Subtree

    I've been using Git for a while now, both at work and also for my iOS projects. I'm really liking it and have nearly sorted out my workflow with it. One problem that remains for me though is how to manage external dependencies. If I need to include a library from Github for example, how do I integrate it with my source.

    The main issues that I want to solve are

    • What happens if the external library disappears? This is especially relevant for online sources like Github. Given the brittle nature of the web, I think we can take it as a given that a lot of these Github repositories will be deleted over the coming years. In this scenario I need to have a local copy of the code as a backup.

    • I should be able to update the local code with the latest or a specific tag from the external repository.

    • I want to be able to create common libraries for my own code which I can share between applications.

    • It may be that I will need to modify the code, so how do I maintain those changes. Perhaps I will need to push those changes to the external repository. This seems likely for my own common libraries.

    • I want to be able to check out all the code needed to build an application from the source control using a single checkout/clone command. This means that each application will have a full copy of all the code that is needed to build it.

    One solution that I've seen used in other projects is to use git submodule links. A git submodule points to a version of an external repository. The ones I've seen for iOS libraries will usually point to Github. When you run the git submodule init command, git will follow these links and download the source into your project.

    However in researching this, other people have reported problems using git submodules. They don't seem as simple and as usable as I would need. I'm seeing issues on sites regarding detached heads, branching, different versions etc. I just know that I will hit all these issues and probably a few more besides!

    In looking for an alternative I came across git subtrees on Wolf Rentzsch's site. This seems to fit all my needs and appears less error prone than git submodules. The code can be downloaded here and here's a good tutorial on using subtrees.

    My basic usage of it, i.e. to integrate a library from Github would be something like git subtree add --prefix=GCUtils/External/CocoaLumberjack --squash https://github.com/robbiehanson/CocoaLumberjack.git master I use the squash option to compress all the commit history of the library to just one commit message in my repository.

    One issue I ran into was adding a project which itself contained submodules. In this situation I search and find all the .gitmodules files and add those manually as subtrees in my repository.

    posted on November 5, 2012development


    Setting up Calabash on iOS

    I've been implementing some new features in iOS and in the process refactoring some existing code. As I've been making these changes, I began to feel that the code was reaching a tipping point where I was as likely to break existing features as successfully add the new functionality. In particular I was experimenting with table view controllers and there are a lot of functions to override depending on what behaviour you want. I was finding that changes for one type of behaviour were impacting functionality that I thought I had solved previously. I hadn't been doing much automated testing up to now apart from some unit testing, so I was worried about adding regression bugs.

    I decided to take a break from coding in order to implement some proper tests and specifically I wanted to do some UI testing. For this I chose the Calabash framework. This is developed by the people at Less Painful. One of them, Karl Krukow, has a detailed post comparing Calabash to the other automated frameworks out there.

    Cucumber

    Calabash is based on a Ruby test framework called Cucumber. Cucumber allows for tests to be written in high level language called Gherkin. Gherkin is written in natural language and so can be understood by anyone - not just developers. It acts as documentation as well as a test framework. I could see this as being very useful when writing an application for a client. By giving them the Cucumber tests, they can see in plain English what is being implemented and should be able to give constructive feedback. Also the tests are automated and are run from the command line.

    While learning Cucumber the two main resources I used were

    • The Cucumber website which has a number of tutorials and a great wiki.
    • The Pragmatic Programmers' Cucumber book. This is an excellent book. I highly recommend reading this before implementing any tests.

    Installation

    Cucumber requires Ruby to be installed on your system (I had previously installed it while setting up Octopress). The Calabash install process is documented on their Github page. I used the Fast Track installer using these steps.

    • gem install calabash-cucumber
    • calabash-ios setup
    • calabash-ios sim acc
    • calabash-ios gen

    This created initial test files which you can run from the command line using cucumber.

    One thing that worries me about the install process is that it creates a new scheme specifically for Calabash use. I don't really like this solution as it breaks DRY and requires keeping the original scheme and the new Calabash scheme in sync. From my experience in programming, anything that is required to be kept manually in sync, won't be. I would have preferred for the Calabash libraries to only be included in the Debug target of the main scheme or for a new target to be created on that scheme. Update: Since I wrote this post Trevor Harmon has been in touch with an alternative approach to just link in the libraries for the Debug build - more info here.

    A good blog on the Calabash install and initial test setup is here.

    First Steps with Calabash

    • I think the Calabash wiki is the best starting point for Calabash.

    • The first thing I tried was the console using calabash-ios console. I recommend this to play around and see what objects are visible to Calabash.

    • The command query("view") shows everything on screen. We can isolate specific views by filtering on the accessibility label. In some cases this wasn't useful for me. For example, I have a table where each cell has a text field. Each of these has the same accessibility label so instead I filtered using the :text property.

    • We can find out what accessibility labels are visible using label "view". Once we have a label we can do things like touching or swiping on the view or checking that the view exists using view_with_mark_exists().

    • The accessibility inspector can be used to identify the classes of UI elements and the on-screen hierarchy. Launch this from XCode under the menu item XCode->Open Developer Tool->Accessibility Inspector.

    • I found that the built-in Calabash steps were very useful to base mine on.

    • A problem I had was querying for the currently active textfield from a table of textfields. The issue was that all those textfields had the same placeholder text. To get the correct one I filtered by isUserInteractionEnabled.

    • Errors in the name of the selector passed to the backdoor command show up as connection errors.

    • Initially I struggled with writing the tests at the correct level. The temptation is to be really specific in terms of UI elements e.g. When I touch X button and swipe on Y label. However you really need to describe them at a higher level e.g. when I add a new contact, when I delete an appointment etc.

    • Initially I was unable to run a backdoor command in the before hook, which runs before each test. I had wanted to reset my Core Data database & UI at this time. The reason here is that the Calabash framework itself uses before hooks to connect to the app and I think my hook was being called before theirs. To solve this Calabash added support for defining an on_launch function which is called after the simulator has started. To implement use the following template in the hooks.rb file.

      class CallbackWorld
       include Calabash::Cucumber::Operations
       def on_launch
         # here I can call backdoor and reset the app state
       end
      end
      
      World do
       CallbackWorld.new
      end
      
    • My typical test layout is to use

      • Given to put the system in a specific state - this is where I use the backdoor function to set up the app model. I do things like erase all the Core Data objects here (from Stack Overflow) to ensure that each test starts with a clean slate.
      • When to perform an action. These are driven through the app UI.
      • Then to check the results of the actions. I've typically done these using the app UI e.g. checking for the existence of views, the state of the UI etc. As an alternative I could also use the backdoor function to check the model here.

    Issues with Calabash.

    It wasn't all smooth sailing as I did run into a few issues along the way.

    • I wasn't able to get it to integrate with my installation of Jenkins, which is unfortunate as Cucumber can output in JUnit format so it's a perfect fit for Jenkins. The problem here is on my side as lots of users on the Calabash Google Group are running Calabash from their CI system. I think it due to the jenkins user not being able to launch the iOS simulator. I need to investigate further on this.

      Update: Ru Cindrea emailed me to suggest another way of running Jenkins which may fix this problem.

      I used to launch Jenkins like this: "sudo launchctl load /Library/LaunchDaemons/org.jenkins-ci.plist" - which seems to be the recommended way on a lot of sites I have found.

      However, I now launch it under my own user, using "nohup java -jar /Applications/Jenkins/jenkins.war --httpPort=8080" - and everything works perfectly! I can simply use "cucumber -f junit -o results -f pretty" to start the simulator, run the tests and get my JUnit report.

    • I had found that Calabash would frequently drop the connection to the app and fail the tests as a result. Once a test run started seeing these errors for a test (Unable to make connection to Calabash Server at http://localhost:37265/) then each following test in the run would show the same error. Rerunning the tests would normally sort it out in the next run or two. Both the app and Calabash would be running fine but just couldn't seem to connect to each other. This unreliability was the most disappointing part of the tests for me.

      Update: Karl pointed me to the Google Group and I saw some updates that were needed to work with the new iOS 6 Simulator. I had seen that black screen issue as part of trying to get it working with Jenkins. So I've updated to the latest version of Calabash and on the first test run, everything worked fine. Hopefully this will resolve the issue in future.

    Initial Impressions & Next Steps

    I have to say that I'm very impressed with Calabash and indeed Cucumber in general. I think that writing these type of tests beforehand would be helpful for requirements gathering and feature design. The tests themselves are not only useful as tests but also as documentation. Unlike Word docs, we can be guaranteed that these accurately describe the current state of the system, given that they are actually run against it.

    My plans for the future

    • I need to add more tests. I initially tested this with just a single feature and that's worked out so well that I'll add this to the other features.
    • From now on, I also plan to write these type of tests for a feature before implementing it. I think that the Cucumber tests especially with the language they are written in are very effective when thinking through the behaviour of the app. They force you to describe it in high level terms rather than just diving into coding.
    • My tests currently have a lot of duplication. Once I have written a lot more of them and I gain more Ruby experience, I will look to refactor them.

    Update: After my initial post Karl Krukow emailed me with some updates on the issues I was having and I've integrated those into the blog post. He pointed out that there is a Google Group for Calabash on iOS where you can ask questions and share information.

    posted on October 22, 2012development


    Further Jenkins Setup for iOS

    Last time I went through how I set up jenkins on iOS and built a simple static library. All in all, that process went ok. The next step was to build an actual app. Unfortunately I encountered a lot more issues with this.

    The first error I got was

    Code Sign error: The identity 'iPhone Developer' doesn't match any valid certificate/private key pair in the default keychain` 
    

    This post on Stack Overflow has a really detailed set of instructions on how best to fix this. Unfortunately as my iPhone developer account is not a business one, I can't add a jenkins user to it. So to solve my problem I added my certificate to the system keychain so that now my local jenkins user can access it.

    Once that was out of the way, the next issue to rear its head was a provisioning profile error.

    Code Sign error: A valid provisioning profile matching the application's Identifier '...' could not be found
    

    I found the solution to this again on Stack Overflow. I needed to copy my provisioning profile from ~/Library/MobileDevice/Provisioning to the jenkins user's folder at /Users/Shared/Jenkins/Home/Library/MobileDevice/Provisioning Profiles.

    The next reason for the build failing was that I was invoking xcodebuild using a target instead of a scheme. The target worked fine for the static library but was failing for the app as it was unable to find all the include files. Once I switched to building a scheme, the build worked fine. Building via a scheme or target is easy to configure using the Jenkins XCode plugin. You set the XCode Schema File entry to the name of the XCode build scheme.

    Nearly there! Now that the build was working I turned my attention to getting the unit tests running. The TEST_AFTER_BUILD flag that had worked before wasn't working this time. Fortunately I found the solution on Peter Jihoon Kim's blog. I needed to create a new scheme to run my tests. Once that was done I got this error

    /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Tools/Tools/RunPlatformUnitTests:95: warning: Skipping tests; the iPhoneSimulator platform does not currently support application-hosted tests (TEST_HOST set).
    

    Peter's blog describes the fix for this. You need to patch the RunPlatformUnitTests file in order to remove the warning printout and invoke the tests.

    The last error I had to deal with was with the code coverage. I started seeing errors with fopen$UNIX2003 and fwrite$UNIX2003. I had seen this issue on other blogs before but hadn't encountered it myself until I tried building an app using the command line. The solution as described here is to add implementations of these into your application which simply call the standard C functions.

    #include <stdio.h>
    
    FILE *fopen$UNIX2003( const char *filename, const char *mode )
    {
        return fopen(filename, mode);
    }
    
    size_t fwrite$UNIX2003( const void *a, size_t b, size_t c, FILE *d )
    {
        return fwrite(a, b, c, d);
    }
    

    One unresolved issue was that I couldn't get clang scan plugin working for this setup. I think the issue here is that it was using targets instead of schemes. I left this one go as I didn't feel it important enough to get working. XCode runs this while I'm developing anyway. I may come back to it in future once everything else is stable.

    XCode 4.5 Updates

    So, just when I got everything working for XCode 4.4, along comes XCode 4.5. Ever since the 4.2 to 4.3 transition broke code coverage for me, I've been a bit wary of XCode updates. Sure enough after installing 4.5 and trying to build my app, I got an error message saying that the calabash framework was missing a armv7s slice ld: file is universal (2 slices) but does not contain a(n) armv7s slice: ...calabash.framework/calabash for architecture armv7s Calabash is part of an iOS testing framework based on Cucumber. I've just started to implement this form of testing and it looks really nice. Getting back to the build issue, Ash Furrow has a detailed post on this issue. We need to remove armv7s (which refers to the new A6 chip in the iPhone 5) from our valid architectures. Once Calabash gets updated to support this architecture, I can reenable it.

    Once everything built in XCode, it was time to try the jenkins build. Naturally this broke also. The problem was that the XCode plugin couldn't find the 5.1 simulator.

    xcodebuild: error: SDK "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.1.sdk" cannot be located.
    

    XCode 4.5 had wiped out the simulators for 5.1 so I needed to redownload them. I was able to download these from Preferences->Downloads->Components. XCode also prompted me to download the 6.0 simulator so I got that out of the way while installing 5.1.

    Once the simulators were installed I started hitting the same RunPlatformUnitTests error as above. When I opened the script file to reinsert Peter's edits I saw that it had changed slightly. Now the error printout was happening in a function on line 80 which overrode RunTestsForApplication(). I deleted that function and I added back in the original patch at line 118 so that now it looks like

    if [ "${TEST_HOST}" != "" ]; then
        # All applications are tested the same way, by injecting a bundle.
        # The bundle needs to configure and run the tests itself somehow.
        export CFFIXED_USER_HOME="${BUILT_PRODUCTS_DIR}/UserHome/"
        mkdir -p "${CFFIXED_USER_HOME}"
        mkdir -p "${CFFIXED_USER_HOME}/Library/Caches"
        mkdir "${CFFIXED_USER_HOME}/Library/Preferences"
        mkdir "${CFFIXED_USER_HOME}/Documents"
        export OTHER_TEST_FLAGS="${OTHER_TEST_FLAGS} -RegisterForSystemEvents"
    
        RunTestsForApplication "${TEST_HOST}" "${TEST_BUNDLE_PATH}"
    else
        # If no TEST_HOST is specified, assume we're running the test bundle.
    
        RunTestsForBundle "${TEST_BUNDLE_PATH}"
    fi
    

    These changes fixed the 4.5 build issues and now I have a working build and test setup again. Finally!!

    posted on September 20, 2012development


    Setting up Jenkins on OS X

    First post in a long time. I didn't really do much iOS development over the summer and am only starting to get back into it in the past few weeks. I have some draft posts on my dealings with both Core Data and UITableViews and once those features are complete I'll post them.

    Along with coding, I've been looking at adding some build infrastructure for my projects. Having seen Jenkins used at work, I wanted to get a CI system set up for my builds here at home. I want to use it to kick off a build, run the tests and package up the iPhone app. By using something like Jenkins I can automate my build and testing process and also have a record of previous builds.

    Jenkins Install

    The first step was to install Jenkins. They provide a Mac installer - the only annoyance is that it triggers the new OS X Gatekeeper dialog blocking unsigned apps from installing. Then I loaded locahost:8080 in my browser to find that Jenkins wasn't loading and there was no error message telling me what went wrong. D'oh. The issue is that Jenkins requires Java to run but it isn't installed by default on OS X. To install simply type java into a terminal and a message box will appear prompting you to install Java.

    Then I followed the user setup from Moritz Haarmann's blog. I'm not sure if the jenkins account part is still necessary, as when I got to the stage about changing the user name in the plist file, it had already been set to Jenkins. The changing permissions on the Jenkins home folder was needed though. After that I was able to run ssh-keygen and generate some keys.

    Updating Git Workflow

    I installed the Git and XCode plugins from the Manage Jenkins screen with no issues. I then created a simple project to test it out. I just added a git clone step. This failed for me with the following errors

    Failed to connect to repository : Command "git ls-remote -h ..../MyApp.git HEAD" returned status code 128:
    stdout: 
    stderr: fatal: '..../MyApp.git' does not appear to be a git repository
    fatal: The remote end hung up unexpectedly
    

    The problem here is that the repository is on my Dropbox account (as described here). This folder is not visible to the jenkins user. I didn't want to mess around with changing permissions on the Dropbox folder so I looked for an alternative solution. A colleague at work told me about Bitbucket from Atlassian. This is similar to Github but allows for private repositories. As luck would have it, I had already been using another Atlassian product SourceTree to manage my git repositories. This tool works seamlessly with Bitbucket. Once I uploaded my ssh key to Bitbucket I could simply add another remote repository to my local repository and push to it, all from within SourceTree.

    Now that I had a repository on Bitbucket, it was time to integrate that with Jenkins. This turned out to be fairly easy. I uploaded the ssh key for the jenkins account to Bitbucket. The admin page for the repository showed its ssh address so I added a Git build step to the project using that ssh address. When the project is built now, Jenkins will download the latest code from the repository first and then continue on.

    Jenkins Issues

    While Jenkins is mostly working fine now, there were a few issues I've run into. The git checkout isn't working at all using the Git Plugin. Originally it did but then I started getting the following errors FATAL: Could not checkout null with start point 02dbc3e456d6aa6079543eeaa8361bdebe8fac9d hudson.plugins.git.GitException: Could not checkout null with start point 02dbc3e456d6aa6079543eeaa8361bdebe8fac9d at hudson.plugins.git.GitAPI.checkoutBranch(GitAPI.java:956) ...

    Caused by: hudson.plugins.git.GitException: Command "git checkout -f 02dbc3e456d6aa6079543eeaa8361bdebe8fac9d" returned status code 128:
    stdout: 
    stderr: fatal: reference is not a tree: 02dbc3e456d6aa6079543eeaa8361bdebe8fac9d
    

    I wasn't able to find a solution to this so I had to stop using the Git plugin and just add an execute shell build step to clone the Bitbucket git repository. As I add more projects to Jenkins, I'll check if I get the same issues there also.

    Build XCode Project

    The XCode plugin for Jenkins made it really easy to build once setup. You add an XCode build step and configure it as necessary. I chose to do a clean build each time. The project I tested this on was a static library so I didn't need an IPA built or any of the version number updates but they should be useful when building a proper app.

    When I first tried to build I got an error saying You have not agreed to the Xcode license agreements. I needed to run sudo xcodebuild -license in the terminal to fix this.

    In order to run the unit tests, the XCode plugin recommends using two build steps, one to build the app and the other to execute the tests. The reason for this is that the test step requires extra parameters i.e. path to the simulator SDK. If you're using the OCTest framework which comes with XCode then the plugin will listen to the test output and generate JUnit compatible xml files. Jenkins can read these and add the to the build results page.

    Set up Coverage Setting up code coverage for iOS projects is not an easy task. My gcov setup for XCode 4.3 still worked for me but the problem was to integrate this with Jenkins. Coverstory would not be of use here but I found this gcovr script from the Octo Talks blog. Gcovr will convert the gcov output into a cobertura xml file which can be read by Jenkins.

    One problem I had was that for some reason, gcov wouldn't work on the files in the Jenkins workspace. I was getting gcno:cannot open graph fileerrors. Coverstory also didn't work on the files in this location. What worked for me was to copy the gcda and gcno files out to a temp folder under /Users/Shared/Jenkins/Home. Passing the original build location as the root parameter to gcovr allowed the cobertura plugin to find the source code in the html report, while also removing system headers from the coverage report. Here is the script.

    cp -r ${WORKSPACE}/build/${JOB_NAME}.build/Coverage-iphonesimulator/${JOB_NAME}.build/Objects-normal/i386/*.gc* /Users/shared/Jenkins/tmp/${JOB_NAME}
    cd /Users/shared/Jenkins/tmp/${JOB_NAME}
    gcovr -r $WORKSPACE/$JOB_NAME -x > ${WORKSPACE}/coverage.xml
    

    The Octo Talks blog also suggested a number of other metrics which could be captured in Jenkins. I added the SLOC Count and the Clang Build Scan. Both of these required installing tools and then Jenkins plugins which used those tools. This instructions on the blog covered this. Ones that I've put on the someday/maybe list are the PMD plugin and OCLint.

    At the end of all this, Jenkins is working quite well for my simple test project. Next step is to try it out on my app.

    posted on September 16, 2012development


    Localizing iOS Apps

    I was looking at a tutorial for creating a settings bundle for my app and it had separate files for different languages. I realised that I hadn't a clue how to localize iOS applications. I decided I'd better look into it now, rather than at the end of development, in case it required me to change existing code. Much better to implement with localization in mind, than retrofit at the end of development.

    I'm interested to see how many translations I'll be able to include in the app. I'm not sure how easy it will be to do the translation or even how much text there will be to translate. I'm planning a Chinese translation and for sentimental reasons I'll do an Irish translation. I'll probably try to get some European languages done also. I think that once I put in the infrastructure to do one language then adding additional ones shouldn't be too much bother.

    The basics of implementing localization is that you externalize all strings in your application to .strings files and then provide versions of these files for each language you support. The process for creating the basic localization.strings file is outlined here. In your code you can get the localized values for these strings using NSLocalizedString(@"Externalized String Name", @"").

    Localization Tools

    Using this method, we will have to deal with lots of .strings files. Xcode doesn't provide much help here so I looked around for third party apps. I bought Linguan on the Mac App Store and it looks very good. You point it at an Xcode project file and it locates all the .strings files and presents them in a nice table. It can generate text files which you can send on to your translators for them to translate and re-import their translations. I'm very pleased with it so far.

    Apart from having .strings files for strings in the code, I also need to localize the app's storyboards. Albert Mata has a fantastic tutorial on how to do this here. A big problem with localizing storyboards is that changes in one language's storyboards are not propagated to the others. Manually keeping these in sync would be a nightmare. Thankfully there is a handy script here by Ederson Machado, which will update the .strings files for the storyboard and also keep the storyboards in sync. There is a nice video outlining the features of the script here. By adding this script as a build run script, we can ensure that our storyboards are always in sync.

    Localization Workflow

    My localization workflow is as follows:

    • First I created multiple storyboards for each language using the Localization area on the sidebar. This will create a language.proj folder for each language.
    • I ran the localize.py script on the project. This generated the mainstoryboard.strings files in each of the language folders.
    • I manually add these files to Xcode. First I added the English version. Then I clicked the plus button in the Localization sidebar and added the other languages. Xcode is able to find those .strings files and link them to the overall file.
    • I create a localization.strings file to deal with the strings in the code and added all languages.
    • I ran genstrings but I don't think this is needed if you're using Linguan.
    • When I opened the project in Linguan it was able to find all the strings files, including those from the storyboard.

    I'm satisfied now that I have the localization mostly under control. One thing I still need to look at is how does this affect testing. Hopefully any test framework that I used will be able to run the tests in all languages.

    posted on May 19, 2012development


    Starting out with Core Data

    For my project, I need a way to store the model data that I will be generating. I certainly don't want to write a persistence layer for my model objects so I will definitely use a standard library for this. There are a number of options

    • Core Data. This provides an editor to create the objects and XCode will generate the required model classes for me.
    • Use a database like Sqlite directly. Core Data uses a sqlite database behind the scenes but instead I could create one directly and access it using a library like FMVH.
    • A service like Parse.com. This provides an online backend for apps.

    I don't want to use the database directly as I prefer working with objects, so that would rule out sqlite for me. Parse.com is really interesting. Among other things, it provides an online site where you can see the data in a spreadsheet interface. This tutorial shows how you can use Parse.com to implement a todo list website. It's a real pity that iCloud doesn't provide a similar API to allow non-Apple devices access the data.

    In the end I've decided to go with Core Data. The reasons for this are

    • It's an Apple standard library and one of the purposes of writing an app was to learn about iOS and Apple technologies. Where possible I've tried to stick to the Apple way of doing things as I can be sure that this approach will be supported in future - or if there is a new system, then a transition path will be provided.
    • Core Data works on the object level rather than the database level. I've programmed in objects for most of my career so this is familiar to me. I have a working knowledge of databases but I feel more comfortable using OOP.
    • I'm assuming that Core Data should integrate with iCloud better than other approaches. Thinking ahead I'd like to look at iCloud at some stage and learning Core Data first should make that a bit easier.

    Magical Record and Mogenerator

    There are some good Core Data tutorials out there. The best introduction that I found was the Stanford iOS course (lectures 13 & 14). To be honest, the code required to implement Core Data is fairly complex and verbose. To deal with that, I started looking for libraries which would improve the Core Data experience. The best I found is Magical Record. This library simplifies Core Data a great deal and provides loads of helper categories & functions. There is an excellent tutorial on MagicalRecord here. I also found this tutorial really good and it also includes a sample project which uses MagicalRecord.

    Magical Record works well with another tool called Mogenerator. You download a .dmg from the site and install from that. There is a nice tutorial here. Mogenerator generates classes from the Core Data xcdatamodel file. The normal Core Data build can also do this but the advantage of Mogenerator is that it generates a second set of classes for each Core Data entity. This second set will never be overwritten so you can write custom code in these. The first set of classes will be regenerated each time the model gets updated.

    Magical Record is available on Github. Like most iOS projects I've found there, it seems the standard way to integrate this with your project is to copy the source files into your code and work away. I'm not too comfortable with this approach and would prefer to keep third party libraries separate from my code. This would allow me to update these independently and share them between projects. I'll have to look into what options are available for this.

    posted on May 15, 2012development


    Joined the iOS Developer program

    I've been fairly busy with the Start Your Own Business course so I haven't had much time to do iOS programming. It's time to get back into it now though, and so I've just paid my subscription to the iOS developer program. I'm looking forward to being able to run code on an actual device. It's been a bit limiting working on just the simulator and there's nothing like seeing your code running on the final hardware.

    posted on April 29, 2012development


    Where have all the SRPGs gone

    I had a draft post pre-written earlier this year lamenting the decline of the SRPG game genre. In brief, I used to import these types of games all the time from America for my PS2. I assumed that this would continue for the PS3 and really enjoyed Valkyria Chronicles, but after that the genre has pretty much disappeared for the mainstream consoles. Even on PSN and Xbox live, there has been very little released (Vandal Hearts excepted). Modern games seemed to be limited more and more to mass market genres such as the 3D first person shooter.

    However in the past month a surprising new development in game development has kind of invalidated my draft post. Veteran game designers have started to use Kickstarter to seek funding for niche game genres with some amazing results. The first big success on Kickstarter was Tim Schafer, Ron Gilbert and Double Fine raising over three million to make a new adventure game. I love the Monkey Island games so I backed this - it was actually the first thing I'd ever supported on Kickstarter. I have no idea if the game will be any good but given the caliber of the people involved, I think it's in safe hands. To be honest, the videos they've made for the project have been worth the cash already.

    Following on from that Brian Fargo launched a Wasteland 2 project. This is an attempt to revive the party based CRPGs. This was another genre that I really enjoyed and which stagnated recently. Today's publishers aren't willing to put up the cash for these games. I've started to contribute to more of these gaming projects on Kickstarter (including a space based game - FTL and a Norse SRPG - The Banner Saga). Hopefully this will show that there is a sizable market for these games and they will be more likely to be funded in future. It's really interesting how much more invested in the games you feel once you back them on Kickstarter. For example, I'm really enjoying reading the updates from the game developers. If I was an indie developer I would definitely go down this route. The community that the Kickstarter project creates for your game might be as important as the funding itself.

    Another other thing this has made me realize is how much reputation and track record matters. I had never heard of Wasteland 2 before backing it. However once Brian Fargo reeled off the list of games that he'd worked on, i.e. Fallout, Baldur's Gate and Icewind Dale (all of which still sit proudly on my shelf), I had no hesitation in subscribing. I would much rather see people like him develop games instead of leaving it in the hands of companies like Zynga. Trying to learn from this, I think that having a portfolio would be really valuable for a software engineer. Imagine the kind of CV/resume you'd have if you developed one app, website or side project per year and hosted these online. Given the frameworks and services that are out there e.g. Rails, Parse.com, Heroku for the web, iOS and Android for mobile, I think it's never been easier to create quality small scale projects. To be honest I wish I had started something like that years ago. If I was coming out of college now, one of the first things I'd do would be to register my name as a url and start hosting projects there. It's something small but would really pay off down the line.

    posted on April 2, 2012gaming


    Start your own Business Course

    I've signed up for a Start Your Own Business course which is being run by the South Cork Enterprise Board. It's an eight week course taking three hours every Thursday. I've no intention of leaving my current job but if I'm going to be doing this on the side, then I'd like to know how to do it properly and what type of supports are out there.

    I've gone to three nights already and I'm finding it very useful. I think that the process of creating a business plan focuses your mind on what you want to achieve. I've asked myself more questions about what I want to do with this app development in the past few weeks than in the previous two months. It's also interesting meeting people there who are setting up non software businesses and seeing what common problems and tasks we have. It's good to step outside the software/computing world for a bit and get a wider perspective on things. I hope to come out of this with a clear idea of where I want to take the app work and what I need to do to accomplish this.

    posted on March 20, 2012business


    Setting up a Blog on Octopress and Github

    This post documents how I migrated the blog from Wordpress.com to Octopress. There are a number of bloggers who have written about switching their blogs to Octopress. I found these posts very helpful - Scott Muc, Matt Gemmell and Bigdinosaur Blog. The basic sequence of steps I followed was

    • Install Ruby.
    • Install Octopress.
    • Create account on Github.
    • Export previous blog from Wordpress and convert it to Markdown
    • Generate Octopress blog and publish it to Github.
    • In parallel I registered www.gerardcondon.com and set it up so that it pointed to the blog on Github.
    • Setup a drafts folder on Dropbox so that I can write posts from anywhere.

    Ruby Setup

    The first step is to install Ruby. If you want to, you can compile this from the source but the better option is to use a third party tool to install and manage Ruby. The one I used is RVM.

    By default OS X Lion comes with 1.8.7 pre-installed but Octopress needs 1.9.2. (I tried 1.9.3 at first but Octopress reported an error). I read on Stack Overflow that it's not recommended to upgrade the default installation but instead to install the newer version alongside it. RVM is designed to manage multiple versions of Ruby on a system so it's a nice fit here.

    The command to install Ruby is rvm install 1.9.2. However when I tried this I got errors complaining that the C compiler was LLVM based instead of gcc. To get around this I added the following flag rvm install 1.9.2 --with-gcc=clang. Now we can tell RVM to use version 1.9.2 with this command rvm use 1.9.2.

    Install Octopress

    Installing Octopress is very easy once Ruby is installed. The instructions can be found at Octopress Setup. The install command is rake install and then to build your website run rake generate. Octopress takes whatever pages and posts it finds under the source folder and builds these to a static website. These need to have particular file names and contents, so Octopress provides helper commands to generate a new post or page. These are rake new_page["page_title"] and rake new_post["post_title"] respectively.

    Export from Wordpress

    To export from Wordpress I simply used their export tool. This exported all the posts in their own html files. This would have been fine for Octopress but I wanted the whole site in Markdown, so I converted each post from html to markdown and added to the source/_posts folder.

    Host on Github

    Once you have the Octopress blog created you need to host it somewhere. I choose Github as it provides for free hosting of static blogs. Also if I do release some iOS code later it will be on Github, so there's no harm in getting it set up now.

    This site has a very good explanation of what is going on with Github. Basically we build our website locally to a folder named public. We create a repository on Github for our webpage. Octopress then uploads the contents of the public folder to the master branch on this repository whenever we run the rake deploy command. It is recommended that you upload the site source to a source branch on the repository. That way you can always regenerate the website even if you delete the local files.

    Register URL

    I decided to register www.gerardcondon.com for this site as I didn't want to be tied to a Github url in the same way as I was tied to the Wordpress.com one. I didn't need hosting or anything special - just forwarding. I used Namecheap. The price is really cheap for a .com address - only 6 or 7 dollars a year.

    There are instructions on Github Pages on how to set up the forwarding. You need to setup an A record to redirect to www.github.com for your url without the www part, i.e. gerardcondon.com will redirect to www.github.com. Then you need to create a CNAME file in github and then setup a CNAME redirect for the www part of the url, i.e. www.gerardcondon.com redirects to gerardcondon.github.com. However I ran into some problems doing this on the namecheap site. When I tried to setup the CNAME I got the following errors

    Improper records were NOT saved!

    There were issues with some records and they were either set to default or completely removed. Please review the issues below and update again appropriately.

    INVALID_ADDR: 'gerardcondon.github.com/' should not be an IP/ URL for CNAME record. (host name: www)

    However I just connected to the online chat support and the person assigned to me fixed it up in a few minutes - I have to say they were really helpful. This DNS stuff takes a while to settle down - I think it was a day or so before it had propagated out. Since then I've had no trouble with it.

    Octopress tweaks

    I've made a few tweaks to Octopress to suit my own tastes.

    • I changed the indented-lists setting to true in sass/custom/_layout.scss. Previously the numbers and bullets for lists were not in line with the rest of the post text but instead were placed in the left margin.
    • I reduced the size of the blockquotes in the sass/base/_typography.scss file, from 1.2 em down to 1 em to be the same size as normal text.
    • I changed the solarized theme from dark to light in sass/base/_solarized.scss.

    It's really easy to make changes to Octopress, there is a folder called sass with most of the style stuff. There are a few configuration files also which can be updated. One nice thing about checking all this stuff into github is that you can go back and see what style updates you made in previous commits.

    Add Draft folder and sync with Dropbox

    At this stage Octopress was installed on my Macbook Air and working perfectly for me. One limitation of this setup was that I could only edit posts from that machine. I didn't mind only being able to regenerate the site from the Air as that's not a common task, but I wanted to be able to write posts from anywhere. I also wanted the ability to write draft posts and not have Octopress automatically publish those.

    I found a technique for managing draft posts on Frozen Bytes. This allows you to create a drafts folder and provides commands for moving posts between the draft and published state.

    Using this, I created a folder called drafts in Dropbox. I then symlinked to this from inside the sources directory on the Air. All my drafts are now available in Dropbox and I can edit these anywhere. This is especially useful when editing from iOS as there are a number of markdown editors which can edit files on Dropbox.

    Summary

    I think that's everything! It was fairly straightforward in retrospect to set up. The new setup works really well. I'm very happy with the look of Octopress and the editing workflow in markdown is much better than using the Wordpress editor. Looking forward to using it in future.

    posted on March 4, 2012octopress


Next page

Tags

By year

  1. 2020 (14)
  2. 2019 (17)
  3. 2018 (2)
  4. 2017 (11)
  5. 2016 (3)
  6. 2015 (6)
  7. 2014 (3)
  8. 2013 (11)
  9. 2012 (25)