« Q&A: June 14, 2001

Posted by Andy Monitzer on June 14, 2001 [Feedback (0) & TrackBack (0)]

// Question One

In IB there are two draggables, one with a dollar sign in it, and one with a calendar. These appear to be unplaceable. What are they for? Are they just left over, or can I place them?

Answer

These aren't views; they're formatters. You can use them by:

  • dragging one onto a text field, or
  • dragging one into the nib window and hooking it up to the formatter outlet of any text field(s) you want to use it.

answer by: Rick Roe


// Question Two

How do I rename a file?

Answer

In Cocoa, check out NSFileManager, and this method:

- (BOOL)movePath:(NSString *)source toPath:(NSString *)destination handler:handler

answer by: Clyde McQueen


// Question Three

How do I set the icon of a Docklet that appears in the Finder?

Answer

Launch Services does not handle custom bundle icons on OS X 10.0.[123].

You will need to do the same thing Apple did ... paste the icon on to your dockling and use that. The docklings that ship and have custom icons at this time are all icons in the resource fork, not icons in the data fork of some .icns file.

To do this:

  • Create a simple app with your .icns file as it's icon.
  • Build the app.
  • Navigate to the app with your docklings icon and open the finder inspector. Select the app icon and copy (cmd-c) it.
  • Navigate to your built and ready to be shipped dockling and open the finder inspector.
  • Select the generic dockling icon and paste on top of it.

Voila. Now go find a resource fork aware compressor, compress your dockling and ship it.

answer by: Jerald Dawson


// Question Four

Is there an easy way to determine what language (English, Japanese, etc) the user is currently running under OS X?

Answer

You can determine what localizations are being used, but it isn't as simple as you think, and there are usually better ways to do what you want to do (whatever that is).

If you call

CFBundleCopyPreferredLocalizationsFromArray
	(CFBundleCopyBundleLocalizations(CFBundleGetMainBundle()))

you will get an array containing the names of the localizations currently in use within the main bundle. There may be up to two of these at the moment; for example, both en_US and en might be in use, with some region-specific items coming from en_US and some others from the generic en. The entries in this array are in the format used in the main bundle, which might be language names (English, French), language abbreviations (en, fr), or locale abbreviations (en_US, fr_CA). If your bundle is not the main bundle, then you may wish to use your bundle instead of the main bundle in the above.

Do you see why this is complicated, and why I recommend doing something else? Usually you don't want to know the localization in use directly; what you want is to choose some value based on the current localization. If the value you want is a string, or a resource file, or a Resource Manager resource, then the appropriate thing to do is just to make it a localized value, and get it normally using CFBundle or NSBundle APIs. You can do quite a bit with localized strings, resource files, or Resource Manager resources.

For example, if you wanted to display to the user what language he/she was running in, the value you want isn't "French" or "Japanese", it is the correct localized language name; things like "French" or "fr" or "fr_CA" should not be user-visible. So what you want is a localized string.

If you have more complicated information, you can put it in a separate file, or in a Resource Manager resource, or even encode it in a localized string. You could store an arbitrary property list in any of these places, and you can put just about anything in that.

If you have a situation that is somewhat more complicated, you can use CFBundleCopyPreferredLocalizationsFromArray to help you out. For example, if you have a CFDictionary whose keys refer to the localizations you have available (in any format you like) and whose values are the values you want to choose among (which could be anything), then you can get the list of keys, apply CFBundleCopyPreferredLocalizationsFromArray to that, and if the result is non-empty, take the 0th element of the result and look it up in your CFDictionary.

answer by: Douglas Davidson


// Question Five

How do I create an FSSpec from an NSString containg a full path name (like /Users/karl/file1)?

Answer

- (BOOL)makeFSSpec:(FSSpec *)specPtr fromPath:(NSString *)inPath
{
	FSRef fsref;
	OSStatus status = FSPathMakeRef([inPath fileSystemRepresentation],
                                        &fsref, NULL);
	if (status == noErr)
		status = FSGetCatalogInfo(&fsref, kFSCatInfoNone,
                        NULL, NULL, specPtr, NULL);
	return status == noErr;
}
	...

	FSSpec spec;
	if ([self makeFSSpec:&spec fromPath:path]) {
		NSLog(@"fsspec: vol=%d parent=%08x name=%s",
                        spec.vRefNum, spec.parID, &spec.name[1]);
	}

answer by: Tom Waters


// Question Six

I know I've done this before, but I don't recall how to insert an NSAttributedString into an NSTextView, preserving its formatting. Do I have to stick it in the pasteboard first?

Answer

[[myTextView textStorage] setAttributedString: myAttributedString];

answer by: Greg Titus


// Question Seven

I discover I have a namespace collision: When the nib loads, setPyramidRate: gets called with an NSTextField * in the sender parameter. After awakening from the nib, the pyramidRate outlet is nil.

Renaming the action to newPyramidRate: fixes the problem.

I'm guessing I walked into a trap with the NSKeyValueCoding protocol, but darned if I remember being warned of it. Could someone put me out of my misery and point out where this is documented? Obviously this is in a document I want to re-read.

Answer

The rule for outlet connection is as follow:

If you have an outlet foo, first we look for a -setFoo: method and call it if it exists passing the outlet value as parameter. If this method doesn't exist we them look for a instance variable foo and set it directly.

answer by: Henri Lamiraux


// Question Eight

I've got an NSTabView in IB where I unfortunately created the tabs in the wrong order. Is it possible to rearrange the tabs without having to delete and recreate them?

Answer

Arrow keys allow you to move a tab item.

answer by: Henri Lamiraux


// Question Nine

I probably didn't look in the right place, but I can't find anything in Cocoa for using random numbers. Are there any utilities available, or do I just code it up in straight C?

Answer

AFAIK no. You can use any of the C randomizing functions such as rand() or random() in your Cocoa app.

answer by: David P Henderson


Comments
Post a comment