Archive for the 'Developing on Mac OS X' Category

New Tool: CertificateHelper

Saturday, December 31st, 2011

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

Automatically Rearrange Your UI on Rotation

Tuesday, August 10th, 2010

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_

 

NSCharacterSet bug in 10.5

Monday, May 17th, 2010

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_

 

 

The Debugger has exited with status 1.

Tuesday, January 6th, 2009

Yesterday I encountered a very strange bug/feature in Xcode. I just couldn’t run any application in Release configuration anymore. I always got “The Debugger has exited with status 1.” in the run-log. In debug configuration they worked, without Xcode they worked, in gdb they worked, but as soon as I tried to start them in Xcode in Release configuration it didn’t work. Not even a fresh new Project would work.

I tried removing the prefs but that didn’t help. But it seemed to be user-dependent. I could run my Projects in Release configuration when I logged in as another user.

This morning I saw the “GDB Log” setting in the Debugging Prefs. I activated them and compared the logs of Debug configuration and Release configuration. And this really showed the bug. I had a binary of a System-Framework in my Release folder and instead of the system-version it linked the application to this binary. To my bad it was a binary from a different mac, which is still running 10.4. This made the app exit right when it was started.
The solution was as simple as removing this binary from the Release-folder.

This GDB log is really a lifesaver sometimes!

Karsten

Xcode Refactorings

Saturday, September 27th, 2008

I just created yet another class with some instance variables and so missed the functionality of creating accessor methods for these instvars automatically. As I never really looked into the Refactorings of Xcode 3 I didn’t notice that they provide an encapsulation refactoring. Using this on an instvar nicely generates accessor methods. You have to apply it to all your instvars separately, but still it’s a great gain.

One thing they should improve though: why is the refactor command no submenu which shows all the available refactorings? This way the refactoring could be chosen much simpler.

Karsten

The art of linking

Thursday, May 22nd, 2008

Sorry for the bold title, but I’d like to clarify some issue that occurs in latest stage of application building: linking.

Static and dynamic symbol references

When you link your application, the Mac OS X static linker, ld tries to resolve (ie, find) every symbol you reference to in your code. This creates a table which tells the dynamic linker which symbols to bind to at runtime. What happens if you reference a symbol which the static linker cannot find? Build fails. This can happen if you reference symbols defined in loadable bundles or custom frameworks/dynamic library.

A common solution to this is to add the option “-undefined dynamic_lookup” which delegates the job of both finding and resolving references to the dynamic linker (dynamic linking happens at runtime). Although this is an easy solution, it can give many headaches. One problem with this approach is that any mistyped function name won’t result in a compilation error (the same is true misspelled variables and constants declared as extern) but will result in a crash at runtime. As the crash may not happen at launch time you may have an hard time spotting the problem.

Although we’ll see many ways to avoid having to leave symbol lookup to the dynamic compiler, the best way to handle dynamic lookup is to handle it programmatically were needed instead, following the direction found at this ADC article.

Avoiding dynamic symbol references

So here you can find a few quick tips to avoid dynamic symbol lookup where possible.

  • If you are referencing symbol found in a dynamic library or framework, link to it using (respectively) the flags “-l” or “-framework”. If the library/framework isn’t available system-wide make sure that their install path is relative to the application bundle (usually @executable_path/../Frameworks for frameworks). If you only have the framework/library available in binary form, but you are allowed to redistribute it, you can adjust its install path using “install_name_tool”.
  • If you are writing a loadable bundle, and reference symbols defined in the host application, use the “-bundle_loader” option (followed by the path to the host application’s executable) which will cause ld to search for symbols also in the referenced executable.
  • If you are referencing symbols found in a loadable bundle instead, you have to look them up dynamically. In Cocoa you can usually do it through NSBundle. CoreFoundation also provides CFBundle-related functions for this task.

Compatibility and graceful degradation

If some symbols, referenced either statically or dynamically are not found at execution time, the application will crash. We might see this, for example, running an application using Leopard features on Tiger. What if we want to retain Tiger compatibility? We may conditionally reimplement some system provided capabilities or disable some features on the older OS. The Mac OS X linker provides an extremely classy way to handle this kind of situations through correct choice of SDK and Deployment Target.

A common mistake is to use the SDK of the oldest OS we want our application to run on. This isn’t generally a good idea and becomes a problem as soon as we reference symbols defined in newer versions of Mac OS X (ld will fail).

A better idea is to instead use the latest SDK and set the Deployment Target to the oldest version of Mac OS X you want your application to run on. This will cause the static linker to mark references to symbols not defined in system frameworks as of your deployment target of choice (but found in the used SDK) to be marked as “weak references”. Weak references are mostly like regular references, but if binding the symbol fails at runtime, the reference is set to NULL. This gives you a great way to check if a certain symbol is available at runtime and avoids nasty crashes (this does not work for selectors because they are handled by the objective-c runtime, you can check for those using respondsToSelector:).

For your information, weak references are created adding the __attribute__((weak_import) directive to a symbol declaration (usually to externs) but usually don’t need to declare them explicitly (the system frameworks have preprocessor directives to do that automatically based on deployment target).

zsh-bashing to rescue the NSLog

Sunday, March 23rd, 2008

Doing some tool that uses a NSTask to launch shell-scripts, I ran into a very annoying bug these days. The script were bash scripts and as soon as they were started, all output written by NSLog didn’t go to Xcode’s console, but rather only to console.log. This problem only seems to happen when using bash to execute the scripts, so switching to zsh did the trick and now NSLog works as charming as always. Thanks a lot to Michele for the hint with Zsh, I didn’t know that it uses the same syntax as bash and thus the only changes to the scripts were changes to the first line!

thanks a lot for the folks that found this out!

Karsten

inspecting the Pasteboard: Drop Inspector

Sunday, March 2nd, 2008

Today I thought about a nice and easy way to inspect drag and drop objects or any Pasteboard in general. I ended up creating Drop Inspector, a very simple app that shows you the content of the General Pasteboard if you click on the drop area, or the content of the dragging pasteboard if you drag something on the drag area.

One big problem was that Cocoa (or OS X in general) doesn’t allow you to register a view for any draggin types. The app doesn’t even receive the mouse over event if you didn’t register for a certain type. But to solve this i simply added a text-input field where you can enter the identifier of this pasteboard type and click on “add type”.

Drop Inspector is listing all types that are registered in the pasteboard and if you select one it’ll show you the data of these types in a text-editor. That’s not the most useful thing to have, but better than nothing…copy and paste it into the hex-editor of your choice and see what comes out.

A much better way of processing this data is through FScript. So I added a simple FScript editor to the app, enter some code, hit Cmd-I and inspect the result. As most data on the clipboard is string data, the default is:

NSString alloc initWithData:data encoding:NSUTF8StringEncoding.

I guess it should be pretty useful for anyone who wants to add drag and drop support to an application or who wants to extend it and needs to see what kind of data is available.

The app is released under MIT License and includes the source-code. The disc image can be loaded from: DropInspector.dmg

Karsten

PS: oh, and if there’s any icon artist out there with some freetime, willing to create a better icon for DropInspector, please do! :-)

Icon Composer in 10.5

Sunday, December 2nd, 2007

I just had to create an icon and used the new Icon Composer for this. There’re some really great new features in the new version. Not only that it can create icons like the previous version, it also provides a VERY nice preview panel. You can preview your icon in any size from 1px to 512px on ANY background. It also provides the two default wallpapers so that one can immediately see how it looks on those.

Icon Composer Screenshot

Great improvements, especially all those little things that are of such a big help!

Karsten

Update on Xcode Templates

Tuesday, November 13th, 2007

Today I got a mail regarding Xcode Templates and it made me look into it again. I was surprised that Apple changed the way Xcode integrates into the system now. Until 10.5 everything was stored in /Library/, but as of 10.5 Xcode uses the folder /Developer/Library/. Everything related to Xcode is there (especially in the Xcode subfolder): the frameworks, plugins, templates… all of it. The plugins that were installed in 10.4 will have to be moved there I guess (got no time to try out if BSInspectors work yet).

So as of 10.5, install custom project templates in /Developer/Library/Xcode/Project Templates/ :-)