Text

Open Quickly (or Go to File) working in VimR

Finally, after some days of coding, Open Quickly (or Go to File in TextMate) works in VimR. It’s not perfect yet and it does not look pretty, but it works.

When the user first uses Open Quickly for an open window, VimR starts to scan and cache the content of the worspace, ie the common parent directory of the window’s open buffers. The scanning may take a while if the workspace contains many files, eg the user’s home folder. However once done, only folders with file system changes since then will be scanned again. (When the Vim window closes, then the cache of that workspace will be deleted.)

I used some dylibs and functions from TextMate, eg the string ranker to compute the result list of files. Due to the very modular architecture of TextMate, it is quite easy to use them in other Apps. Most likely, in the course of extending VimR, more parts of TextMate will be used.

Text

Minimal MacVim Using MacVimFramework

Some time ago, I did some code-massaging exercise and extracted a Framework part of MacVim: MacVimFramework target in qvacua/macvim on Github.

I (finally) found some time and included an absolute minimal proof-of-concept App that uses the Framework:MinimalMacVimtarget in the Xcode project. Basically it has one class (MinimalMacVim/MMAppDelegate.m) which is the delegate for everything. And for the sake of simplicity it does not handle many things like resizing the Vim-view properly when a new tab is created.

Over the course of time I’ll try to improve the Framework and make it easier to use. (Eg, some delegate methods should/can be handled automatically)

Maybe some other folks will find the Framework useful..

Text

A Toy App: Cataloq

To try out the document-based database Couchbase Lite and the grid view of the OpenEmu project, I created a small toy catalog app: Cataloq

image

You can

  • add/delete items,
  • change thumbnail and display name,
  • tag and rate items,
  • search by display name,
  • change the size of the thumbnail.

Well, that’s basically it.

Text

Notes on Creating a QuickLook Plugin

These are some notes which will be useful for creating a QuickLook plugin.

  • When you create a new QuickLook plugin target, the template will be automatically added to your project.
  • When you want to include some 3rd party frameworks in your plugin, these frameworks have to use @loader_path/../Frameworks as the Installation Directory, not @executable_path/../Frameworks: stackoverflow article
  • To include the plugin in the App as follows

MyApp.app/Contents/Library/QuickLook/MyQuickLookGenerator.qlgenerator

I used the Copy Files build phase with the following

  • Destination: Executables,
  • Subpath: ../Library/QuickLook.

This may not be the smartest way to do it, but it works.

  • qlmanage is your best friend for debugging the plugin.
  • To set qlmanage as the executable for the plugin in Xcode 4, you have to edit the run settings of the scheme. As of now AppCode does not seem to support external executables.
Text

Continuous Integration for Cocoa Reloaded

First do the following:

  1. Open the “Manage Schemes…” dialog and check “Shared” for schemes you want to have available for Jenkins. Xcode generates “xcshareddata” folder inside the xcodeproj file.
  2. Open “Build Settings” for the test target and set “Bundle Loader” and “Test Host” to blank by deleting them.
  3. Create a free-style job.

For tests using OCUnit:

  1. Download ocunit2junit and put it somewhere.
  2. Add an “Execute shell” build step and insert the following
    xcodebuild -scheme NAME_OF_TEST_SCHEME -configuration Debug clean test | /PATH/TO/ocunit2junit
  3. Add the “Publish JUnit test result report” post-build action with **/test-reports/*.xml

For static analysis using clang-analyzer:

  1. Download clang-analyzer and put it somewhere.
  2. Install “Clang Scan-Build Plugin” for Jenkins
  3. Add an “Execute shell” build step and insert the following
    /PATH/TO/scan-build -k -v -v -o clangScanBuildReports xcodebuild -scheme NAME_OF_SOME_SCHEME -configuration Debug clean build
  4. Add the “Publish Clang Scan-Build Results” post-build action
     
Tags: Jenkins Cocoa
Text

Continuous Integration for Cocoa using Jenkins, Part II

Outdated: See Continuous Integration for Cocoa Reloaded

Some time ago, I wrote about how to use Jenkins for Cocoa/iPhone projects. Back then, I used GHUnit which can produce JUnit test results XML files. Recently, I found OCUnit2JUnit which converts OCUnit results to JUnit result XML format. Thus, no more GHUnit. Do the following

xcodebuild -target NAME_OF_TARGET -configuration Debug clean test | /PATH/TO/ocunit2junit.rb

or

xcodebuild -scheme NAME_OF_SCHEME -configuration Debug clean test | /PATH/TO/ocunit2junit.rb

Note that you may have to copy the scheme definitions before executing xcodebuild, see the post How to Use Subprojects with Xcode and Jenkins.

Add “Publish JUnit test result report” step as a post-build action with **/test-reports/*.xml and you’re set!

Text

How to Use Subprojects with Xcode and Jenkins

Assume, you have an Xcode project Parent and another project Child, which is registered as a subproject of Parent. Let’s further assume that Child is registered as a Git submodule of Parent. Imagine that you want to use Jenkins for continuous integration for the project Parent. Do the following:

  1. Make sure that xcuserdata folder in Parent.xcodeproj is included in the Git repository.
  2. Download ocunit2junit.rb. Yay, you don’t need GHUnit anymore!
  3. Create a free-style job in Jenkins and add an “Execute shell” step with the following
    git submodule init
    git submodule update
    git submodule -q foreach git pull -q origin master
    cp -r Parent.xcodeproj/xcuserdata/YOUR_USER_NAME.xcuserdatad Parent.xcodeproj/xcuserdata/JENKINS_USER_NAME.xcuserdatad
    xcodebuild -scheme NAME_OF_OCUNIT_SCHEME -configuration Release clean test | /PATH/TO/ocunit2junit.rb
  4. Add “Publish JUnit test result report” post-build action:
     
  5. Voilà!
Text

Auto Save and Versions

Auto Save and Versions seem only to work in conjunction with the NSFileWrapper-using read/write method of NSDocument, ie

– readFromFileWrapper:ofType:error:
– fileWrapperOfType:error:

If you use only

– readFromURL:ofType:error:
– dataOfType:error:

then you get a warning that the file cannot be autosaved after having done the following:

  1. Restore a version of the document
  2. Modify the document
  3. Close the document

Source: cocoa-dev mailing list

Tags: cocoa
Text

Argument Captor for Objective-C

For my small projects Qmind and Qdesktop I needed a Objective-C counterpart of Mockito’s ArgumentCaptor. As far as I can see, OCHamcrest or OCMockito do not offer this functionality. Thus, I wrote an OCHamcrest matcher which does the job: ArgumentCaptor.zip

Example:

ArgumentCaptor *captor = argCaptor();

[someMock someMessage:someArgument];
[verify(someMock) someMessage:captor];

id argument = captor.argument;
assertThat(argument, is(someArgument));

BTW, I’m using the ARC.

Tags: cocoa testing
Text

AppCode, OCUnit, GHUnit, CI and All That

Outdated: See Continuous Integration for Cocoa Reloaded

I am using AppCode for not-so-daily Cocoa coding sessions. Therefore, I want to use its nice OCUnit integration—similar to the JUnit integration of IntelliJ. At the same time, I do not want to give up the CI integration of GHUnit. To combine both, I did the following.

  • Set up your GHUnit target denoted by ghunit.
  • Create a new OCUnit target denoted by ocunit.
  • Let test classes inherit from SenTestCase.
  • At this stage, the ocunit can be run using Product->Test in XCode or by setting and running a new OCUnit Run Configuration in AppCode.
  • If you try to run ghunit, it will fail saying that the SenTestingKit framework is not loaded. You have to set the environment variable DYLD_FALLBACK_FRAMEWORK_PATH to include /Developer/Library/Framework: conversation in the xcode-users mailng list. To do this, create the following property file in ~/.MacOSX/environment.plist
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
    	<key>DYLD_FALLBACK_FRAMEWORK_PATH</key>
    	<string>/Library/Frameworks:/Network/Library/Frameworks:/System/Library/Frameworks:/Developer/Library/Frameworks</string>
    </dict>
    </plist>
  • Write some tests.
  • That’s it!
Tags: jenkins cocoa
Text

Continuous Integration for Cocoa

Outdated: See Continuous Integration for Cocoa Reloaded

Using GHUnit and Jenkins, it is quite straight-forward to set up continuous integration environment for Cocoa—also iOS—projects.

  • Set up GHUnit and write some awesome tests
  • Makefile (put this in the project root folder)
    default:
    	# Set default make action here
    	# xcodebuild -target Tests -configuration MyMainTarget -sdk macosx build	
    
    clean:
    	-rm -rf build/*
    
    test:
    	GHUNIT_CLI=1 GHUNIT_AUTORUN=1 GHUNIT_AUTOEXIT=1 xcodebuild -target NAME_OF_TEST_TARGET -configuration Debug -sdk macosx build
    
  • Put RunTests.sh of GHUnit in the project root folder
  • I modified main.mto the following to be compatible with ARC and to make sure that the tests are run parallelly
    //
    //  GHUnitTestMain.m
    //  GHUnit
    //
    //  Created by Gabriel Handford on 2/22/09.
    //  Copyright 2009. All rights reserved.
    //
    //  Permission is hereby granted, free of charge, to any person
    //  obtaining a copy of this software and associated documentation
    //  files (the "Software"), to deal in the Software without
    //  restriction, including without limitation the rights to use,
    //  copy, modify, merge, publish, distribute, sublicense, and/or sell
    //  copies of the Software, and to permit persons to whom the
    //  Software is furnished to do so, subject to the following
    //  conditions:
    //
    //  The above copyright notice and this permission notice shall be
    //  included in all copies or substantial portions of the Software.
    //
    //  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    //  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
    //  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    //  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
    //  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
    //  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    //  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
    //  OTHER DEALINGS IN THE SOFTWARE.
    //
    
    #import <GHUnit/GHUnit.h>
    #import <GHUnit/GHTestApp.h>
    
    // Default exception handler
    void exceptionHandler(NSException *exception) { 
        NSLog(@"%@\n%@", [exception reason], GHUStackTraceFromException(exception));
    }
    
    int main(int argc, char *argv[]) {
        
        /*!
         Default:   Set to:
         NSDebugEnabled                        NO       "YES"
         NSZombieEnabled                       NO       "YES"
         NSDeallocateZombies                   NO       "YES"
         NSHangOnUncaughtException             NO       "YES"
         
         NSEnableAutoreleasePool              YES       "NO"
         NSAutoreleaseFreedObjectCheckEnabled  NO       "YES"
         NSAutoreleaseHighWaterMark             0       non-negative integer
         NSAutoreleaseHighWaterResolution       0       non-negative integer
         
         For info on these varaiables see NSDebug.h; http://theshadow.uw.hu/iPhoneSDKdoc/Foundation.framework/NSDebug.h.html
         
         For malloc debugging see: http://developer.apple.com/mac/library/documentation/Performance/Conceptual/ManagingMemory/Articles/MallocDebug.html
         */
        NSSetUncaughtExceptionHandler(&exceptionHandler);
        int retVal = 0;
    
        @autoreleasepool {
            // Register any special test case classes
            //[[GHTesting sharedInstance] registerClassName:@"GHSpecialTestCase"];  
            
            // If GHUNIT_CLI is set we are using the command line interface and run the tests
            // Otherwise load the GUI app
            if (getenv("GHUNIT_CLI")) {
                //        retVal = [GHTestRunner run];
                GHTestRunner *testRunner = [GHTestRunner runnerFromEnv];
                testRunner.inParallel = YES;
                [testRunner runTests];
                retVal = (int)testRunner.stats.failureCount;
            } else {
                // To run all tests (from ENV)
                GHTestApp *app = [[GHTestApp alloc] init];
                // To run a different test suite:
                //GHTestSuite *suite = [GHTestSuite suiteWithTestFilter:@"GHSlowTest,GHAsyncTestCaseTest"];
                //GHTestApp *app = [[GHTestApp alloc] initWithSuite:suite];
                // Or set global:
                //GHUnitTest = @"GHSlowTest";
                [NSApp run];
            }
    
        }
        
        return retVal;
    }
  • Create a new Jenkins free-style job with the following command
    make clean && WRITE_JUNIT_XML=YES make test
    and
     
Tags: jenkins cocoa
Text

Analyzing Objective-C Code Using Jenkins

Outdated: See Continuous Integration for Cocoa Reloaded

Using Jenkins, you can automatically execute Clang’s static analyzer each time you commit to your local Git repository.

First, download the binary files, unpack them somewhere and install the Clang Scan-Build Plugin in Jenkins. Then, create a new free-style job with the following

[ -e clangScanBuildReports ] && rm -r clangScanBuildReports
[ -e build ] && rm -r build
mkdir build
/PATH/TO/scan-build -k -v -v -o clangScanBuildReports xcodebuild -target NAME_OF_TARGET -configuration Debug clean build

Finally, activate “Publish Clang Scan-Build Results” and optionally set your threshold:

Tags: cocoa jenkins
Text

Building a Cocoa App via Jenkins

After some heavy Cocoa coding, I want to build my application in the Release configuration for deployment—well, I must admit that my app is not quite ready yet—, I have to archive it using Xcode and share it. If you are aware of a shortcut, please let me know.

Having set up Jenkins on my machine, I wanted Jenkins to do it for me. This is how:

  1. Create a new free-style Job and name it appropriately, for example Deploy
  2. In the “Build” section enter the following
    [ -e build ] && rm -r build
    xcodebuild -target NAME_OF_TARGET -configuration Release clean build
    cd build
    zip -r NAME_OF_APP-LATEST.zip Release/NAME_OF_APP.app
  3. Archive the artifacts build/APP-LATEST.zip

That’s it! Now, one could think of automatically uploading the zip file to some FTP server or something like that…

Text

Thin divider of NSSplitView

To make the divider of an NSSplitView really thin, i.e. 1px, it does not suffice to set the divider type to “Thin.” You have to set the border type of both embedded views, assuming that they are both subclasses of NSScrollView, to NSNoBorder. This means in Xcode

By default NSBezelBorder, the third button in the picture, is selected which results in

By having no borders, you get

which looks much better.

Tags: cocoa
Text

Icons inside toolbar controls

Assume that you want to create a toolbar like the Mail application. The Icon Design Guidelines in the Apple’s HIG says that the icon should measure no more than 19 x 19 pixels and should be in the PDF format. However, PNG works fine, too. More importantly, if we want to have the inner shadow effect,

than the name of the image must end with “Template.” As far as I can see, this is not documented in the HIG.

Tags: cocoa