CuteClips and Snapplr for sale

January 5th, 2015 by Karsten

The last few years have been pretty busy on my end. I still work as a full-time Smalltalk developer and in my spare time I’ve released some new versions of my Apps, most of which are available on the Mac App Store. Last year I’ve even released my first iOS App: Hectare.app

However, I’ve also neglected two of my products severely. Both Snapplr and CuteClips have not seen an update in years. During a longer journey before Christmas I made the decision to sell both apps because I believe my customers deserve better than me not having time to update the apps.

Read the rest of this entry »

New Tool: CertificateHelper

December 31st, 2011 by Karsten

Last fall I got a new iMac that I only use during the Weekends. I’ve just recently noticed that I still didn’t have Code Signing running. I’ve done quite some searching and even tried to debug what codesign does when it tries to match certificates. Only then I noticed that even though I had all certificates in place, the problem was that these Certificates needed the private key as well. The fix was as simple as exporting and importing the private key from one mac to the other.

As I’ve had problems with Code Signing before, I decided that it’d be a lot more helpful to not have to google around the webs like crazy over and over again but instead have some app that contains the knowledge and gives proper tips.

The result is CertificateHelper, which you can find over at GitHub. Currently it only supports those problems that I was having (no certificates/no private key).

To add new Problems to the app, simply subclass CertificateProblem and implement the following methods:

  • + (void) load – here you need to call [self registerSubclass] so that the app finds this new problem
  • + (id) problemIfExists – this method returns an instance of the class or nil, depending of if the problem exists or not
  • – (NSString*) htmlDescription – a small snippet of HTML code that describes the problem and how to solve it
  • – (NSArray*) infoObjects – objects that are displayed at the bottom list, if needed (defaults to an empty array
  • – (ProblemSeverity) severity – returns the severity of the problem. If multiple problems occur, this value is used to sort the problems. The one with the highest severity is then displayed to the user.

I think the most problematic part of the implementation is the work with the keychain. There’s the CertificateAccess class right now which tries to simplifies that.

Karsten

Camouflage 2.0

June 28th, 2011 by Karsten

After several years without update, Camouflage 2.0 was just released. It is available in the Mac App Store for only $1.99.

Probably the most important new feature is compatibility with upcoming versions of Mac OS X. There’re were several bugs and crashes fixed, especially the bug where the Camouflage menu would be all gray after choosing a HotKey. CoreAnimation is now used for wallpaper transitions. So if you change your wallpapers it now fades like on the original Desktop.

One more thing of notice is that Camouflage 2.0 will now tell other applications when it hides the Desktop Icons. I’ve already contacted the developer of GeekTool and he likes the idea to support Camouflage, so stay tuned for news on that. On a technical side, this works by posting the distributed notifications “CamouflageWindowsAppear” and “CamouflageWindowsHidden”. The first notification also includes a dictionary with the window numbers and window levels. So if you’re writing a software that shows information behind the Desktop icons, you might want to register for those notifications and in case Camouflage activates, increase your windows’ window levels in order to be in front of Camouflage.

A word on version 1.25, which was and still is free. If you’re using Mac OS X prior to 10.6, you can still use that version. It has its limitations, but works. If you’re using 10.6 i can’t stop you from using version 1, but if you feel like supporting an indie mac developer, please update to version 2.

@_karsten_

NSConf 2011 recap

April 7th, 2011 by Karsten

Already two weeks ago, NSConference 2011 closed after three full days of joy. Three days of meeting lots of interesting people. Three days of listening to insanely great talks that both widened your view as well as broadened your horizon.

One point that was mentioned throughout the conference in almost all of the talks: Pay attention to the details! Go that extra mile, it’s totally worth it!

And NSConf payed a lot of attention to the details. Here’re some details that I’d like to point out:

– the talks were always 30 minutes long with a 30 minute pause to the next talk. In this 30 minute pause there was a 15 minute Blitz-Talk. The Blitz-Talk was in a room 50m to walk from the main room. So every 30 minutes people were getting up and had a little bit of an exercise. Or they were getting up for some coffee and food 🙂

– 30 minute talks were extremely good to follow. Even if you were not interested in the subject at all, you didn’t even have time to do something else, cause 30 minutes later the talk was already over. So you could as well just stay and listen.

– there was only one track of talks to follow, no multiple tracks.

– The Wifi was free, but it was slow. ICQ et al didn’t work, only Skype. Twitter worked very good and for mail it was enough too, so people typically followed the talks instead of surfing the webs.

– I cannot remember how many talks exceeded the 30 minutes time limit, but it must have been only very few, so thanks again to the speakers for not talking too long.

– the people from the US were happy to have one hour less of a jet-lag due to the conference falling in the two-week gap between US summertime and european summertime.

– not only were the days scheduled for the talks, but the evenings were also taken care of. So you basically only needed to book the hotel for bed and breakfast!

– the first night was a dinner with fantastic food. I really didn’t expect that great food in the UK (no offense, but the UK is not famous for their food as France or Italy are). But not only was the food extraordinarily delicious, the wine was excellent, too!

– the food also proved to be a great foundation for the party after the dinner 😉

– the second night was a party with rodeo riding, sumo wrestling and playstation… and an iPad2 lottery

– they even had a magician at the party! how cool is that?

– did I already mention that there was drinks and food served every break? During lunch we could even sit outside in the sun eating our food.

– the sun was shining! (when I visited London in July that was not the case, so I’m a bit surprised here)

– the bar had Staropramen beer (lovely czech beer) this year!

– the hotel replaced their public pc’s with some shiny iMacs.

– probably the most important part: in the lobby was the conference help desk! Whenever you thought you had a problem, you could go there and you would see that there is no problem that could not be solved. These guys not only managed the checkin, they were there the whole conference and they even helped with checking out and getting to the airport in time!
I only needed to tell these guys when my flight went and they figured the trip out for me. They even got me to the mortimer train station. Thanks a lot, that was amazing!

I’m already looking forward to next years NSConf!

@_karsten_

Handcrafting object files

September 28th, 2010 by Karsten

The Problem:

Image you’ve got a c-file with the following code:

 

unsigned char text[] = { 0x53, 0x6f, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x79, 0x6f, 0x75,
 			 0x27, 0x76, 0x65, 0x20, 0x67, 0x6f, 0x74, 0x20, 0x61, 0x20, 0x63, 0x20,
 			 0x66, 0x69, 0x6c, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68,
 			 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20,
 			 0x63, 0x6f, 0x64, 0x65, 0x3a, 0x0a, 0x0a };
long textSize = sizeof(text);

not too hard to imagine, isn’t it? Now imagine you’ve got a bit more data. Like 20MB of data. Storing 20mb of data in a c-file probably doesn’t use the best compression. You would end up in a text-file of 100mb+. Compiling such a file takes quite some time and more importantly takes plenty of ram. Dealing with that kind of files isn’t the best thing to do so I thought about a better solution.

It would be much better to store the binary file in…a binary file ;-). But you can’t just link to a random binary file and access its data. One would also want to have the data’s value available in a variable.

The solution

..is pretty easy actually: store the data in a static library and link your app against that library. This library could also export a symbol or two. One to get the data, one to get the size.

But as easy as the solution sounds, how do you get a static library out of a binary file? Or more importantly, how do you generate an object file? That’s pretty easy with a compiler. One could use gcc to compile the object file. Only problem is that gcc takes c-files as input, which kinda defeats the purpose.

I’ve chosen a different compiler, I’ve chosen as. As, for those who don’t know, is the assembler in gcc. It takes cpu instructions and converts them to bytes in an object file. But it can actually do a lot more. There’re plenty of special instructions available that don’t convert to machine code but rather decide where things go in the resulting object file. There’re instructions to declare a global, to define data, etc. A very handy instruction is the .space size, fill instruction. It allows us to create an area of bytes of a certain length. The instruction is just one line, but can generate space for tons of megabytes if you like. Using the .space instruction we can generate object files of a certain size, free to be filled with whatever we like.

The workflow for putting binary files inside a static library is like so: you generate the assembler file, compile it into an object file, link it to a static library via libtool and then you replace the placeholder inside the static library with the contents of the binary file.

Don’t worry. There’s no need to do that by hand. I’ve released DataLibraryCreator which does exactly that.

Using this technique you can do other pretty cool stuff, too. Like creating symbol files for times when you want to debug c-tools that don’t ship symbols (like here). If you compile a c-file via

cc -S myFile.c

you’ll get a myFile.s which contains the assembler code generated out of the c-file. If you aren’t to sure about which instructions you can use in the assembler file, just try and see what the c-compiler generates.

@_karsten_

 

Automatically Rearrange Your UI on Rotation

August 10th, 2010 by Karsten

Last weekend I’ve started to write my first real iPhone app. At one point I thought that the app worked pretty well in Portrait mode, but it could also work pretty nicely in Landscape mode.

However, I didn’t just want to rotate each view but instead have a different layout of the view. I didn’t want to hardcode all the positions so I though about something along the lines of creating a second xib file that works as a template to arrange the original xib’s views for landscape.

It turns out that this is actually pretty easy. As long as the views are in the same structure in both xib files, one can just traverse the view tree by iterating over the subviews of a view.

I’ve created a class called BSUIViewRearranger. It can be used pretty easily by calling the following code in your view controller:

[BSUIViewRearranger rearrangeView: self.view
                            toMode: toInterfaceOrientation 
                 usingLandscapeNib: @"MainViewLandscape" 
                       portraitNib: @"MainView"
                   controllerClass: [self class]];

 

just put that inside your -willRotateToIntefaceOrientation:duration: method and you’re done. Optionally one can wrap it in a view animation block like so:
[UIView animateWithDuration:duration animations:^(void) {
 // code here
}];

I’ve released the code on github in case someone wants it.

@_karsten_

 

Dealing with Crashlogs

July 21st, 2010 by Karsten

I’ve already written about why every developer should know his way around with otx so this is sort of like a follow up on this topic.

Today Peter Hosey asked on Stack Overflow about an interesting stack trace. Obviously the writeWithFormat() function didn’t crash recursively. So it appears that the crashlog is lying to us about the function that makes trouble. No need to panic, there’s plenty of useful information left in the crashlog to help us find the bug. First of all there are offsets:

0   com.growl.GrowlSafari        0x179d383c writeWithFormat + 25
1   com.growl.GrowlSafari        0x179d388e writeWithFormat + 107
2   com.growl.GrowlSafari        0x179d388e writeWithFormat + 107
... 

So the first frame is at offset 0x179d383c and all the other frames are at offset 0x179d388e. The only way to make sense out of these numbers is to use otx to disassemble the binary and look at the offsets to find out what’s really being called (the current svn version of otx is much more current, if you don’t mind compiling the tool yourself).

Before we can start disassembling we first need to know which file to disassemble. Fortunately the crashlog contains that information at the very beginning.

Process:         Safari [2062]
Path:            /Applications/Safari.app/Contents/MacOS/Safari
Identifier:      com.apple.Safari
Version:         5.0 (6533.16)
Build Info:      WebBrowser-75331600~5
Code Type:       X86 (Native)
Parent Process:  launchd [84]
PlugIn Path:       /Applications/GrowlSafari.app/Contents/Resources/GrowlSafari.bundle/Contents/MacOS/GrowlSafari
PlugIn Identifier: com.growl.GrowlSafari
PlugIn Version:    1.2.1 (1.2.1)

So i’m sure everyone agrees that Safari doesn’t need to be disassemble, even though the crashlog says so in the Path. The crashlog is kind enough to tell us which plugin causes the crash, so we can take the plugin’s path as input to otx and pipe it to TextWrangler‘s command line tool:

otx -arch i386 /Applications/GrowlSafari.app/Contents/Resources/GrowlSafari.bundle/Contents/MacOS/GrowlSafari | edit

Another indication to disassemble the plugin are the frames, as they all contain the identifier of their bundle: com.growl.GrowlSafari.

So now we have the disassembly of the plugin, but the offsets of the crashlog cannot be found. The offsets produced by otx start at 0x00000f54 and go to 0x000024f3. That’s not nearly close to 0x179d383c. The reason behind that is simple: the plugin’s code is mapped into the memory where the linker things it got some space left. So we need to find out where the plugin was mapped in order to find the right spot in the disassembly.

Again, the crashlog got all the information that is needed. At the end of the crashlog is a list of all the plugins, frameworks and bundles, that are loaded into the application at the time when the crashlog was taken.

It looks like:

Binary Images:
    0x1000 -   0x526ffb  com.apple.Safari 5.0 (6533.16) <5CC91F2A-7709-6B9E-069D-C6E408F1A14B> /Applications/Safari.app/Contents/MacOS/Safari
 0x1340000 -  0x1340ffc +com.growl.GrowlSafariLoader 1.1.6 (1.1.6) <BF586D9F-39A9-BD06-1C83-6F1E527822CA> /Library/InputManagers/GrowlSafari/GrowlSafariLoader.bundle/Contents/MacOS/GrowlSafariLoader
 0x13b3000 -  0x13b3ff7  com.apple.JavaPluginCocoa 13.2.0 (13.2.0) <6330F04D-3250-2071-42E4-0ABB54216529> /System/Library/Frameworks/JavaVM.framework/Versions/A/Resources/JavaPluginCocoa.bundle/Contents/MacOS/JavaPluginCocoa

So the first two numbers are the start and end offsets of the mapped binary. The application itself is typically mapped to the beginning, which always starts at 0x1000. The provided information also includes the bundle identifier, version numbers, a unique id and the path. I have actually no idea what the + before com.growl.GrowlSafariLoader stands for, so if anyone knows, please tell me :-).

Searching for our bundle identifer reveals this line:

0x179d2000 - 0x179d4ff7 +com.growl.GrowlSafari 1.2.1 (1.2.1) <10F1EF69-D655-CCEE-DF3A-1F6C0CF541D3> /Applications/GrowlSafari.app/Contents/Resources/GrowlSafari.bundle/Contents/MacOS/GrowlSafari

It appears that 0x179d2000 is our base offset. Subtracting that from our offsets gives us the offsets 0x183c and 0x188e. Subtracting is pretty easy in our case, but in general subtracting hex numbers is done easiest in gdb:

p/x 0x179d383c - 0x179d2000

Now that we have our correct offsets, we can have a look at the disassembly of that offset to see what’s going on.

SafariGrowl disassembled

i’ve already added some comments at the two offsets that are shown in the stack trace. First thing that one sees is that the disassembly has proper method names and the offsets both are inside the myInitWithDownload:mayOpenWhenDone:allowOverwrite: method. At offset 0x188e (the offset that all the frames show) there’s a movl instruction, but this is not the instruction we are looking for. The instruction right before the movl is a calll instruction. As the name suggest, it calls a function but on return it continues at offset 0x188e, which is why we see this offset in the stack trace. Otx is kind enough to annotate the calll instruction with Objective-C-like comments that show which function is called. It appears that the function calls itself, thus causing a recursion and the crash. Usually one wouldn’t program a function to call itself, but in that case the method is part of a MethodSwizzle, where this is normal behavior (MethodSwizzling can be done easily with Wolf Rentzsch‘s JRSwizzle project).

So why is the method swizzling not working in our case? The answer is again shown in the crashlog: there are actually two versions of the plugin loaded into Safari at the same time.

 0x140c000 -  0x140efff +com.growl.GrowlSafari 1.1.6 (1.1.6) <1E774BDF-5CC5-4876-7C66-380EBFEAF190> /Library/InputManagers/GrowlSafari/GrowlSafariLoader.bundle/Contents/PlugIns/GrowlSafari.bundle/Contents/MacOS/GrowlSafari
0x179d2000 - 0x179d4ff7 +com.growl.GrowlSafari 1.2.1 (1.2.1) <10F1EF69-D655-CCEE-DF3A-1F6C0CF541D3> /Applications/GrowlSafari.app/Contents/Resources/GrowlSafari.bundle/Contents/MacOS/GrowlSafari

I think the reason for the crash is that both plugins define the same method and when the second plugin swizzles its methods, the original implementation of Safari is probably swizzled out and only the two patched methods are left. I think the older patch is called first, resulting in a call to the new patch, which then recursively calls itself. Maybe before swizzling two methods one should check if there was a swizzle before and reverse it before applying a second swizzle.

But those mind swizzling details are probably not too important for the actual fix for this crash and also don’t have much to do with our little excursus to crashlogs-wonderland. I hope you enjoyed the trip 😀

@_karsten_

NSCharacterSet bug in 10.5

May 17th, 2010 by Karsten

I’ve just ran across a pretty unexpected bug in CuteClips. I was using NSCharacterSet to filter a String. This kept locking up some users computers. Turns out this is a bug in Mac OS X 10.5. Snow Leopard doesn’t show this bug so I guess it’s useless to report that to Apple.

The bug is pretty easy to reproduce:

NSMutableCharacterSet* characterSet = [NSMutableCharacterSet whitespaceAndNewlineCharacterSet];
[characterSet formUnionWithCharacterSet:[[NSCharacterSet alphanumericCharacterSet] invertedSet]];
NSString* longString = @””;
NSString* shortString = [longString stringByTrimmingCharactersInSet:characterSet];

The #stringByTrimmingCharactersInSet: Method will never return though. The easiest workaround is to check if the longString is empty, as the bug appears for empty strings.

@_karsten_

 

 

Xcode Run Script Build Phase debugging

March 25th, 2010 by Karsten

So I wanted to add a new build phase to my Xcode Project to run some shell script. It didn’t want to work and I’ve tried to find out why it didn’t work so I’ve tried some Logging. That turned out to be a bit tricky first as i’ve set Xcode to hide all messages and only show warnings and errors. To work around this you simply need to create warnings or errors. That’s pretty easy actually as you only need to write “warning: ohoh” or “error: meh” and Xcode will automatically annotate the message as warning or error:

echo "warning: ohoh"
echo "error: meh"

Error Messages in Xcode

@_karsten_

PlistExplorer on GitHub

January 18th, 2010 by Karsten

Ok, your wishes are heard. I’ve cleaned up the code and added PlistExplorer to GitHub.

you can find it at: http://github.com/karstenBriksoft/PlistExplorer

Karsten (@_karsten_)