Cocoa
TTStyledText problems with ampersand (’&')
by Warlock on Apr.25, 2010, under Cocoa, iPhone
I ran across an interesting problem today where I was trying to use TTStyledText from the Three20 project to create a TTStyledTextLabel that had text with links nested within it. I was trying to
Map here.
I was doing this with the following (simplified code):
[TTStyledText textFromXHTML:@"Map <a href=\"http://www.google.com/maps?f=q&hl=en\">here</a>." lineBreaks:YES URLs:YES];
As soon as I tried to put a URL in that had multiple URL parameters (and thus an &) things would disappear.
From briefly looking at the Three20 source code, I believe this because the parsing of the XHTML text is being done with an XML parser. As soon as I replaced the &s with &s things started to work. This can be done using the following code:
[@"Map <a href=\"http://www.google.com/maps?f=q&hl=en\">here</a>." stringByReplacingOccurrencesOfString:@"&" withString:@"&"];
Cocoa/UIKit BulbView
by Warlock on Jun.18, 2009, under Cocoa, iPhone
In my continuing saga to bring old-school displays to new-school (word?) devices, I’ve created a “bulb view” that displays characters in a grid of “lights”. The best way to describe it is probably just to see it:
Like previous LCD view you can set the colors for the lit & dim bulbs, but improved from the LCD view, you can use letters, numbers, and most punctuation/special characters. Again the rendering is done in pure Quartz2D.
The source, including demo apps for both the Mac and iPhone, can be found here. With this view I was smart and made it conditionally compile various parts so that it can be used on either the iPhone or the Mac, without needing separate files.
Conditional Compilation for iPhone
by Warlock on Jun.17, 2009, under Cocoa, iPhone
I’m working on a view right now that I want to be able to cross compile as either an NSView for the Mac, or a UIVIew for the iPhone. I originally wrote it for Leopard, but now I’m trying to add the precompiler directives to let it cross compile between the two platforms. A quick Google search didn’t reveal anything, here are the possible definitions you can use:
#define __MAC_10_0 1000 #define __MAC_10_1 1010 #define __MAC_10_2 1020 #define __MAC_10_3 1030 #define __MAC_10_4 1040 #define __MAC_10_5 1050 #define __MAC_10_6 1060 #define __MAC_NA 9999 /* not available */ #define __IPHONE_2_0 20000 #define __IPHONE_2_1 20100 #define __IPHONE_2_2 20200 #define __IPHONE_3_0 30000 #define __IPHONE_NA 99999 /* not available */
This definition comes from Availability.h located at /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk/usr/include/Availability.h (for the iPhone 3.0 SDK).
Obviously, the __MAC_10_x is actually for the version of OSX, and the __IPHONE_x_x is for iPhone.
So, if you wanted to have code conditionally compile for the iPhone (assuming 3.0 SDK) you would do something like the following:
#ifdef __IPHONE_3_0
// iPhone
#import <UIKit/UIKit.h>
#else
// Mac
#import <Cocoa/Cocoa.h>
#endif
CGColorCreateGenericRGB Error on iPhone SDK 3.0
by Warlock on May.26, 2009, under Cocoa
While porting some Core Graphics/Quartz 2D code from the Mac to the iPhone, I ran across the following error:
error: 'CGColorCreateGenericRGB' is unavailable (declared at
/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk/System/Library/Frameworks/CoreGraphics.framework/Headers/CGColor.h:31)
Looking in the header file in question (CGColor.h), I found the following:
/* Create a color in the "Generic" RGB color space. */
CG_EXTERN CGColorRef CGColorCreateGenericRGB(CGFloat red, CGFloat green,
CGFloat blue, CGFloat alpha)
CG_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
So the header file pretty much confirms what the error says; the function is not available on the iPhone.
After a little bit of looking through documentation, you just have to specify the color space manually and then give the components to the color. So the this:
CGColorCreateGenericRGB(0.90625, 0.80, 0.80, 1.0)
would become
CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
const CGFloat myColor[] = {0.90625, 0.80, 0.80, 1.0};
CGColorCreate(rgb, myColor);
CGColorSpaceRelease(rgb);
Cocoa LCD Screen View
by Warlock on May.25, 2009, under Cocoa
As part of an iPhone application I’m developing, I need a view that will display numbers/times in a way that will look like an old liquid crystal display calculator. I looked around at using various fonts to cover the same effect, but I wanted the look where you could slightly see the non-lit components of the display. As such, I delved into the mystical world of Quartz 2D.
MTILcdView allows you to set three parameters: the color for the “lit” crystals, the color for the “dim” crystals, and the text to be displayed. The view currently only supports displaying numbers plus the colon (”:”) per my needs, but it could easily be extended to display letters as well. The view decides the size of the digits to be displayed based on the height of the view, so for a given height you must adjust the width of the view to allow the needed number of characters to be displayed.
The source code for the Mac is available here: MTILcdView.h, MTILcdView.m. A complete demo application using the view can be retrieved from GitHub here.
The source code for the iPhone 3.0 SDK is available here: MTILcdView.h, MTILcdView.m (note that you must manually rename the files from MTILcdView1.{h|m} to MTILcdView.{h|m}). A complete demo application using the view can be retrieved from GitHub here.
UIButton Title Text Does Not Display
by Warlock on May.14, 2009, under Cocoa
Ran into a minor problem today when I was attempting to manually create a UIButton in my iPhone app. I attempted to create/configure the button through code similar to the following:
CGRect frame = CGRectMake(0, 0, 200, 52);
UIButton b = [[UIButton alloc] initWithFrame:frame];
b.titleLabel.text = @"My Button";
b.titleLabel.textColor = [UIColor whiteColor];
b.backgroundColor = [UIColor clearColor];
The key mistake is highlighted in red. I attempted to manually set the text an color of the UIButton’s label, when in fact the UIButton would automatically reconfigure the label (including it’s text) in response to state changes.
The correct approach is to use send the setXXX:forState: messages to the UIButton object itself. For example, the following code sets the text/color for the UIControlStateNormal state.
[b setTitle:@"Test" forState:UIControlStateNormal];
[b setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
CoreData Development Techniques
by Warlock on Apr.01, 2009, under Cocoa, Database, Software Development Tools, Xcode
I’m just getting started with CoreData, and I’ve been excited about about its nice graphical environment to define your model.
CoreData’s approach to ORM is somewhat different than other tools, such as Hibernate, because it takes advantage of Objective-C’s dynamic nature, and avoids some of the clutter problems you experience with more statically typed languages. Instead of providing mapping information for classes that are defined elsewhere, all modeled objects are instances of NSManagedObject and the system customizes the accessors on the created objects based on the schema.
This is very nice when you are defining your model, and when you can use things like Cocoa Bindings to provide much of the system’s behavior based on state of the model, but when you need to start writing custom controller logic, it isn’t very readable to have everything going around as an NSManagedObject. You can use the dynamically generated properties on these objects, but you will get compiler warnings. Annoying.
You can certainly subclass NSManagedObject and tell the model to use your implementation. This is necessarily if you are going to provide custom behavior on the model objects above the simple data oriented behavior CoreData provides for you. Xcode will even generate source code for you from your data model.
While in the data model editor, do File, New File… and select Managed Object Class from the Cocoa category.
Choose the location where your files will be generated.
Select the model entities for which classes will be generated and click Finish.
The problem with this approach is that you are stuck manually keeping the model and the custom classes in sync. You can certainly regenerate, but if you have made any changes to the files, they will be overwritten.
One alternative to this manual update process is a tool, mogenerator, that will automatically generate custom classes for you. It even goes so far as two generate two classes for each model object:
NSManagedObject <— GenClassA <— GenClassB (where <— represents inherits from). This allows you to modify the code in GenClassB and leave GenClassA alone, which stores the core information from the model. This way you can regenerate GenClassA as needed, without overwriting your custom behavior in GenClassB. PyrusMalus has an introduction on how to get started with mogenerator, Important Shock has a discussion about the approach used by the tool, and Cocoa & Medicine has a description of how to run mogerator from within Xcode using Apple Script.
There is some dissension about if the method of generating custom classes is a good thing. On this thread on CocoaBuilder Ben (who appears to be from Apple according to LinkedIn) seems to be against the idea, though I his main objection is to the idea that the custom accessors generated by NSManagedObject are slower than those statically generated by mogenerator.
One of Apples recommended approaches to avoid compiler warnings is to created categories for NSManagedObject so that the compiler accepts that the accessors you are using are actually there. Xcode provides the ability to copy the attribute declarations for use in these categories (or in custom classes), but to cover everything, you need to copy two separate sets of declarations and paste them into the code. You could use the Xcode custom class generation to get the signatures you need, but there is a still a bit of manual work in the process.
In my opinion, Apple needs to work more to help developers with this problem. I like the approach taken by mogenerator, and I would like to see that same regenerative ability in the built-in Xcode tools, using the 2-class generation-gap design pattern to allow you to make changes to the generated classes without having the changes overwritten next time you re-generate.
Twin Cities User Groups
by Warlock on Mar.12, 2009, under .NET, Announcements, Cocoa
This post is going to serve as a bookmark page for me for all the software development user groups in the Twin Cities area. Please feel free to post links to other groups in the comments and I’ll try to keep this list up-to-date.
| Group/Link | Topics | Meet Schedule |
| Cocoaheads | Objective-C/Cocoa/Mac | 2nd Thursday per Month 6 p.m. |
| Developers Guild | .NET | irregular |
| Languages Group | Languages/Compilers/Lexing/Parsing | 2nd Thursday per Month 5:30 p.m. |
| Silverlight Users Group | .NET/Silverlight/WPF | irregular |
| .NET Users Group | .NET | irregular |
| Java Users Group | Java | irregular |
| Zope/Python Users Group | Python | inactive |
| XNA User Group | XNA | 3rd Thursday per Month 6 p.m. |
| Ruby Users of Minnesota | Ruby | Last Monday per Month 7 p.m. |
| TC Lispers | Lisp | irregular |
Note to site owners: RSS is nice so it’s easy to receive updates about upcoming events.
UPDATE: Central Standard Tech is the definitive reference for technical user groups in the Twin Cities metro area. Thanks @HamletDRC!
Xcode Keyboard Shortcuts
by Warlock on Jan.28, 2009, under Cocoa, Xcode
Right now I’m working on becoming efficient at using Xcode. I’m sure it will take me a while to get really fast in it, but for now I figured I’d better start collecting useful resources.
Here is a good list of keyboard shortcuts for Xcode via this site. Update: the Pages file from which the PNG was generated is available here.
Cocoa Date Formats
by Warlock on Jan.01, 2009, under Cocoa
I’m posting this here mostly for quick personal reference. Below is the date format strings used by NSCalendarDate this information was taken from here.
|
Conversion Specifier |
Description |
|---|---|
|
%% |
a ‘%’ character |
|
%a |
abbreviated weekday name |
|
%A |
full weekday name |
|
%b |
abbreviated month name |
|
%B |
full month name |
|
%c |
shorthand for %X %x, the locale format for date and time |
|
%d |
day of the month as a decimal number (01-31) |
|
%e |
same as %d but does not print the leading 0 for days 1 through 9 |
|
%F |
milliseconds as a decimal number (000-999) |
|
%H |
hour based on a 24-hour clock as a decimal number (00-23) |
|
%I |
hour based on a 12-hour clock as a decimal number (01-12) |
|
%j |
day of the year as a decimal number (001-366) |
|
%m |
month as a decimal number (01-12) |
|
%M |
minute as a decimal number (00-59) |
|
%p |
AM/PM designation for the locale |
|
%S |
second as a decimal number (00-59) |
|
%w |
weekday as a decimal number (0-6), where Sunday is 0 |
|
%x |
date using the date representation for the locale |
|
%X |
time using the time representation for the locale |
|
%y |
year without century (00-99) |
|
%Y |
year with century (such as 1990) |
|
%Z |
time zone name (such as Pacific Daylight Time) |
|
%z |
time zone offset in hours and minutes from GMT (HHMM) |






