Suggestions in popover for NSTokenField - objective-c

I'm trying to subclass NSTokenField to show a popover with token suggestions.
I set my subclass as the super delegate, I intercept the – tokenField:completionsForSubstring:indexOfToken:indexOfSelectedItem: delegate method and return nil to prevent the menu from showing. It works fine except by returning nil the token field doesn't complete the string entered by the user.
Currently I'm using the following lines in – tokenField:completionsForSubstring:indexOfToken:indexOfSelectedItem: to add the suggested string:
NSText *editingText = [[self window] fieldEditor:NO forObject:self];
NSString *suggestionString = [filteredStrings objectAtIndex:0];
NSString *missingPart = [(NSString *)suggestionString substringFromIndex:[substring length]];
NSUInteger insertionPoint = [editingText selectedRange].location;
NSMutableString *currentStringPlusSuggestionString = [[editingText string] mutableCopy];
[currentStringPlusSuggestionString insertString:missingPart atIndex:insertionPoint];
[editingText setString:[stringWithSuggestionString copy]];
Unfortunately it generates an error when I try to insert text between 2 tokens. Here is the error but I don't really understand why the string is out of bounds.
[NSBigMutableString _getBlockStart:end:contentsEnd:forRange:stopAtLineSeparators:]: Range or index out of bounds'
0 CoreFoundation 0x00007fff88835716 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff8adae470 objc_exception_throw + 43
2 CoreFoundation 0x00007fff888354ec +[NSException raise:format:] + 204
3 Foundation 0x00007fff8efd6627 -[NSString _getBlockStart:end:contentsEnd:forRange:stopAtLineSeparators:] + 157
4 AppKit 0x00007fff8bd37c6f _NSFastFillAllLayoutHolesForGlyphRange + 285
5 AppKit 0x00007fff8bd008fa -[NSLayoutManager textContainerForGlyphAtIndex:effectiveRange:] + 238
6 AppKit 0x00007fff8bb4a18f -[NSTextView(NSSharing) didChangeText] + 194
7 AppKit 0x00007fff8bbe00ee -[NSTokenFieldCell textView:willChangeSelectionFromCharacterRange:toCharacterRange:] + 776
8 AppKit 0x00007fff8bd32795 -[NSControl textView:willChangeSelectionFromCharacterRange:toCharacterRange:] + 112
9 AppKit 0x00007fff8bd30724 -[NSTextView(NSSharing) setSelectedRanges:affinity:stillSelecting:] + 1076
10 AppKit 0x00007fff8bcf8438 -[NSLayoutManager textStorage:edited:range:changeInLength:invalidatedRange:] + 406
11 AppKit 0x00007fff8bcf828a -[NSTextStorage _notifyEdited:range:changeInLength:invalidatedRange:] + 154
12 AppKit 0x00007fff8bda0f75 -[NSTextStorage processEditing] + 202
13 AppKit 0x00007fff8bc02c54 -[NSTextStorage endEditing] + 79
14 PopoverTokenField 0x0000000100002f55 -[JSTokenField tokenField:completionsForSubstring:indexOfToken:indexOfSelectedItem:] + 1013
Alternatively, does anyone know another way to let the token field complete the string without having the menu?

Related

Trying to make this work... (Xcode for mac NOT iPhone) - ArrayController

I'm writing a stopwatch application for mac, and am currently working on the 'laps' feature. I am putting the laps into a Table View for better organization. I'm using an Array Controller to put things into the table.
Basically, what I'm trying to do is this:
[arrayController addObject: [NSMutableDictionary dictionaryWithObjectsAndKeys:#"Lap 1",
#"lapNumber", nil]];
That works fine and dandy, but I'd like to be able to control that number next to lap using an integer representing the number of laps, called numLaps. Thus, my code would be:
[arrayController addObject: [NSMutableDictionary dictionaryWithObjectsAndKeys:#"Lap %i",
numLaps, #"lapNumber", nil]];
However, as that is more than two commas before the nil, I think the program is getting screwed up. I am getting the following thrown in the console, though I don't exactly understand what it means / how to fix it:
2013-09-03 16:52:31.515 Popup[3242:303] +[NSMutableDictionary dictionaryWithObjectsAndKeys:]: second object of each pair must be non-nil. Or, did you forget to nil-terminate your parameter list?
2013-09-03 16:52:31.519 Popup[3242:303] (
0 CoreFoundation 0x00007fff9800a0a6 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff9920b3f0 objc_exception_throw + 43
2 CoreFoundation 0x00007fff97fe8e31 +[NSDictionary dictionaryWithObjectsAndKeys:] + 433
3 Popup 0x00000001000035a0 -[PanelController btnLapWasClicked:] + 192
4 AppKit 0x00007fff96082a59 -[NSApplication sendAction:to:from:] + 342
5 AppKit 0x00007fff960828b7 -[NSControl sendAction:to:] + 85
6 AppKit 0x00007fff960827eb -[NSCell _sendActionFrom:] + 138
7 AppKit 0x00007fff96080cd3 -[NSCell trackMouse:inRect:ofView:untilMouseUp:] + 1855
8 AppKit 0x00007fff96080521 -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] + 504
9 AppKit 0x00007fff9607fc9c -[NSControl mouseDown:] + 820
10 AppKit 0x00007fff9607760e -[NSWindow sendEvent:] + 6853
11 AppKit 0x00007fff96073744 -[NSApplication sendEvent:] + 5761
12 AppKit 0x00007fff95f892fa -[NSApplication run] + 636
13 AppKit 0x00007fff95f2dcb6 NSApplicationMain + 869
14 Popup 0x0000000100001652 main + 34
15 Popup 0x0000000100001624 start + 52
)
Any ideas how to implement what I'm trying to do in another fashion that won't confuse the program?
Thanks.
You should use the modern obj-c notation. That enables you to create dictionaries and arrays in a more natural way.
NSDictionary *dic = #{#"Laps ": #(numLaps), #"someotherkey":#"anditswalue"};
In the code you show the keys and values are not in pairs. You must always insert pairs. (For detailed reference see the NSDictionary documentation.)
NSString *key = #"laps";
NSString *value = [NSStringWithFormat:#"Lap %i", numLaps];
[arrayController addObject: [NSMutableDictionary dictionaryWithObjectsAndKeys:
value, key, nil]];
Also, you need to think over what you want to store in the dictionary. The keys and values are not apparent in your example.

Getting error after execute NSMutableArray

Here is the code. I tried to create a object which includes the name, size and image(get from the resource) and then I add that object into NSMutableArray in order to show those object in NSTableView. However, after I run the code, I did get the correct counts of object in NSMutableArray and correct information in each object(name,size,image), but it still gives me error. Could you guys help me. I am a new Mac developer. Thanks !!
Here is the code:
#implementation AppDelegate{
NSMutableArray* _tableContents;
}
-(void)awakeFromNib{
NSString* imagePath = #"USB.png";
NSString* mountPath = #"/Volumes";
_tableContents = [[NSMutableArray alloc]init];
for(mountPath in [[NSWorkspace sharedWorkspace]mountedLocalVolumePaths])
{
if(0==[mountPath rangeOfString:#"/Volumes/"].location)
{
NSString* USBpath = [[[NSWorkspace sharedWorkspace]mountedLocalVolumePaths]objectAtIndex:count];
//get the name of USB drive
NSString* nameOfUSB = [USBpath substringFromIndex:9];
//get the size of USB drive
NSNumber *volumeSize;
NSURL *mountPathPicked = [NSURL fileURLWithPath:mountPath];
if([mountPathPicked getResourceValue:&volumeSize forKey:NSURLVolumeTotalCapacityKey error:nil])
{
NSDictionary *obj = #{#"name":nameOfUSB,
#"image":[NSImage imageNamed:imagePath],
#"size":volumeSize
};
//after I call the following line, it will give me error !!
[_tableContents addObject:obj];
}
}
count ++;
}
}
//I also use the following two methods in order to show the name, and image in NSTableView
-(NSInteger)numberOfRowsInTableView:(NSTableView *)tableView{
return [_tableCountents count];
}
-(NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row{
NSDictionary *flag = _tableContents[row];
NSString *identifier = [tableColumn identifier];//call different col we need identifier
if([identifier isEqualToString:#"MainCell"])
{
NSTableCellView *cellView = [tableView makeViewWithIdentifier:#"MainCell" owner:self];//give back specific cell named mainCell
[cellView.textField setStringValue:flag[#"name"]];
[cellView.imageView setImage:flag[#"image"]];
return cellView;
}
return nil;
}
There is no connection problems in GUI. And here is the error message:
2013-04-25 01:16:41.321 NAMEOFPROJECT[8243:303] An uncaught exception was raised
2013-04-25 01:16:41.322 NAMEOFPROJECT[8243:303] *** -[__NSArrayI objectAtIndex:]: index 7 beyond bounds [0 .. 3]
2013-04-25 01:16:41.329 NAMEOFPROJECT[8243:303] (
0 CoreFoundation 0x00007fff9147cb06 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff900c03f0 objc_exception_throw + 43
2 CoreFoundation 0x00007fff9142fb53 -[__NSArrayI objectAtIndex:] + 163
3 CDTOANYDRIVE 0x00000001000011d6 -[AppDelegate DetectingUSBDrives] + 710
4 CDTOANYDRIVE 0x0000000100000efb -[AppDelegate awakeFromNib] + 43
5 AppKit 0x00007fff899631a8 -[NSIBObjectData nibInstantiateWithOwner:topLevelObjects:] + 1234
6 AppKit 0x00007fff89b79976 -[NSNib _instantiateNibWithExternalNameTable:] + 610
7 AppKit 0x00007fff89b7a41a -[NSNib instantiateNibWithExternalNameTable:] + 17
8 AppKit 0x00007fff89b262b4 -[NSTableRowData _unarchiveViewWithIdentifier:owner:] + 520
9 CDTOANYDRIVE 0x000000010000174b -[AppDelegate tableView:viewForTableColumn:row:] + 219
10 AppKit 0x00007fff89b279a2 -[NSTableRowData _addViewToRowView:atColumn:row:] + 324
11 AppKit 0x00007fff89b2766f -[NSTableRowData _addViewsToRowView:atRow:] + 151
12 AppKit 0x00007fff89b25c05 -[NSTableRowData _addRowViewForVisibleRow:withPriorView:] + 415
13 AppKit 0x00007fff89b2598a -[NSTableRowData _addRowViewForVisibleRow:withPriorRowIndex:inDictionary:withRowAnimation:] + 272
14 AppKit 0x00007fff89b24c59 -[NSTableRowData _unsafeUpdateVisibleRowEntries] + 740
15 AppKit 0x00007fff89b247f1 -[NSTableRowData updateVisibleRowViews] + 119
16 AppKit 0x00007fff89afc5d7 -[NSTableView layout] + 165
17 AppKit 0x00007fff89aafe95 -[NSView _layoutSubtreeHeedingRecursionGuard:] + 112
18 CoreFoundation 0x00007fff914754a6 __NSArrayEnumerate + 582
19 AppKit 0x00007fff89aafff6 -[NSView _layoutSubtreeHeedingRecursionGuard:] + 465
20 CoreFoundation 0x00007fff914754a6 __NSArrayEnumerate + 582
21 AppKit 0x00007fff89aafff6 -[NSView _layoutSubtreeHeedingRecursionGuard:] + 465
22 CoreFoundation 0x00007fff914754a6 __NSArrayEnumerate + 582
23 AppKit 0x00007fff89aafff6 -[NSView _layoutSubtreeHeedingRecursionGuard:] + 465
24 CoreFoundation 0x00007fff914754a6 __NSArrayEnumerate + 582
25 AppKit 0x00007fff89aafff6 -[NSView _layoutSubtreeHeedingRecursionGuard:] + 465
26 AppKit 0x00007fff89aafd2e -[NSView layoutSubtreeIfNeeded] + 615
27 AppKit 0x00007fff89aab4dc -[NSWindow(NSConstraintBasedLayout) layoutIfNeeded] + 201
28 AppKit 0x00007fff899d96a8 -[NSView _layoutAtWindowLevelIfNeeded] + 99
29 AppKit 0x00007fff899d8fe6 -[NSView _sendViewWillDrawInRect:clipRootView:] + 87
30 AppKit 0x00007fff899a59b1 -[NSView displayIfNeeded] + 1044
31 AppKit 0x00007fff89a62a48 -[NSWindow _reallyDoOrderWindow:relativeTo:findKey:forCounter:force:isModal:] + 1377
32 AppKit 0x00007fff89a62068 -[NSWindow _doOrderWindow:relativeTo:findKey:forCounter:force:isModal:] + 940
33 AppKit 0x00007fff89a61c4f -[NSWindow orderWindow:relativeTo:] + 159
34 AppKit 0x00007fff89963266 -[NSIBObjectData nibInstantiateWithOwner:topLevelObjects:] + 1424
35 AppKit 0x00007fff8994214d loadNib + 317
36 AppKit 0x00007fff89941679 +[NSBundle(NSNibLoading) _loadNibFile:nameTable:withZone:ownerBundle:] + 219
37 AppKit 0x00007fff899414ae -[NSBundle(NSNibLoading) loadNibNamed:owner:topLevelObjects:] + 200
38 AppKit 0x00007fff8994128e +[NSBundle(NSNibLoading) loadNibNamed:owner:] + 360
39 AppKit 0x00007fff8993da2f NSApplicationMain + 398
40 CDTOANYDRIVE 0x0000000100000e82 main + 34
41 libdyld.dylib 0x00007fff9385a7e1 start + 0
42 ??? 0x0000000000000003 0x0 + 3
)
And the above error shows twice !!
I have tried your code in a mini-app and It works fine. There are few things that I might highlight:
Your exception occurs in the method DetectingUSBDrives, for which we don't have any code. I'm assuming that you have pasted the code in the awakeFromNib method.
You are using count as an index. Is this varibale initialized at zero?
The fact that the error appears twice suggests that your cell views hold a reference to your app delegate, which means that awakeFromNib is called once for each view creation. This can create many problem since you are initializing _tableOfContents there. You might want to move all that code to the init method instead.

UILabel [__NSCFString set]: unrecognized selector sent to instance crash

I am having a weird crash related to a UILabel but the crash reporting service I am using doesn't give me much help to locate it. I can't know which Controller and which UILabel is causing it. The only help I have is the following:
-[__NSCFString set]: unrecognized selector sent to instance 0x1e0958d0
0 CoreFoundation __exceptionPreprocess + 162
1 libobjc.A.dylib objc_exception_throw + 30
2 CoreFoundation -[NSObject(NSObject) doesNotRecognizeSelector:] + 170
3 CoreFoundation ___forwarding___ + 392
4 CoreFoundation _CF_forwarding_prep_0 + 24
5 UIKit -[UILabel _legacy_drawTextInRect:baselineCalculationOnly:] + 2632
6 UIKit -[UILabel _drawTextInRect:baselineCalculationOnly:] + 166
7 UIKit -[UILabel drawTextInRect:] + 450
8 UIKit -[UILabel drawRect:] + 72
9 UIKit -[UIView(CALayerDelegate) drawLayer:inContext:] + 364
10 QuartzCore -[CALayer drawInContext:] + 112
11 QuartzCore CABackingStoreUpdate_ + 1808
12 QuartzCore CA::Layer::display_() + 980
13 QuartzCore CA::Layer::display_if_needed(CA::Transaction*) + 202
14 QuartzCore CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 24
15 QuartzCore CA::Context::commit_transaction(CA::Transaction*) + 238
16 QuartzCore CA::Transaction::commit() + 316
17 QuartzCore CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 60
18 CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 20
19 CoreFoundation __CFRunLoopDoObservers + 276
20 CoreFoundation __CFRunLoopRun + 742
21 CoreFoundation CFRunLoopRunSpecific + 356
22 CoreFoundation CFRunLoopRunInMode + 104
23 GraphicsServices GSEventRunModal + 74
24 UIKit UIApplicationMain + 1120
25 App main.m line 14
26 App start + 40
Is there anything I can find my way through this? Thanx in advance!
Even though it's an old question, for anyone that encounters a similar issue:
If you're using attributedText in your UILabel, check the attribute value types you're setting. For example:
NSString* s = #"str";
NSMutableAttributedString* as = [[NSMutableAttributedString alloc] initWithString:s];
[as addAttribute:NSForegroundColorAttributeName value:someObjectThatsNotAUIColor range:NSMakeRange(0, s.length)];
will cause the UILabel [__NSCFString set]: unrecognized selector sent to instance crash.
You could try to put this in a .h :
#interface NSString (extended)
- (void)set;
#end
And this in a .m :
#implementation NSString (extended)
- (void)set
{
NSLog(#"[NSString set] ??? impossible !!!");
}
#end
Then set a breakpoint on this method.
Search your project for " set]" then you'll probably already find it, as this is a very untypical method name. If that doesn't help, use NSLog to print out all your labels adresses to your console to find out which label is causing this. Like
for (UIView *sub in self.subviews)
if ([sub kindOfClass:[UILabel class]]) NSLog(#"%p", sub);
(code untested, correct spelling if necessary)

Get iTunes Artwork for Current Song with ScriptingBridge

I have been trying to figure out how to get the iTunes artwork for the currently playing song with scripting bridge. I have gotten to a point where it works for some songs, but for others, I get a SIGABRT. I'm not sure what the issue could be, so any help would be greatly appreciated. Here is what I have so far:
iTunesApplication * iTunes = [SBApplication applicationWithBundleIdentifier:#"com.apple.iTunes"];
NSImage *songArtwork;
iTunesTrack *current = [iTunes currentTrack];
iTunesArtwork *artwork = (iTunesArtwork *)[[[current artworks] get] lastObject];
if(artwork != nil)
songArtwork = [artwork data];
else
songArtwork = [NSImage imageNamed:#"Image.tiff"];
NSMenuItem *artworkMenuItem = [[NSMenuItem alloc] initWithTitle:#"" action:NULL keyEquivalent:#""];
[songArtwork setSize:NSMakeSize(128, 128)];
[artworkMenuItem setImage:songArtwork];
[Menu insertItem:artworkMenuItem atIndex:0];
I for some songs it works, and displays the artwork nicely in the menu item, but for others I get a SIGABRT on the line:
[songArtwork setSize:NSMakeSize(128, 128)];
The output of the console is as follows:
2011-08-12 23:13:20.094 SongViewer[2146:707] -[NSAppleEventDescriptor setSize:]: unrecognized selector sent to instance 0x102827f70
2011-08-12 23:13:20.095 SongViewer[2146:707] An uncaught exception was raised
2011-08-12 23:13:20.096 SongViewer[2146:707] -[NSAppleEventDescriptor setSize:]: unrecognized selector sent to instance 0x102827f70
2011-08-12 23:13:20.097 SongViewer[2146:707] (
0 CoreFoundation 0x00007fff86f11986 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff8b04cd5e objc_exception_throw + 43
2 CoreFoundation 0x00007fff86f9d5ae -[NSObject doesNotRecognizeSelector:] + 190
3 CoreFoundation 0x00007fff86efe803 ___forwarding___ + 371
4 CoreFoundation 0x00007fff86efe618 _CF_forwarding_prep_0 + 232
5 SongViewer 0x0000000100002a83 -[IPMenulet awakeFromNib] + 4483
6 CoreFoundation 0x00007fff86f089e1 -[NSObject performSelector:] + 49
7 CoreFoundation 0x00007fff86f08962 -[NSSet makeObjectsPerformSelector:] + 274
8 AppKit 0x00007fff8d9d9c27 -[NSIBObjectData nibInstantiateWithOwner:topLevelObjects:] + 1245
9 AppKit 0x00007fff8d9d01b9 loadNib + 322
10 AppKit 0x00007fff8d9cf6b6 +[NSBundle(NSNibLoading) _loadNibFile:nameTable:withZone:ownerBundle:] + 217
11 AppKit 0x00007fff8d9cf5d1 +[NSBundle(NSNibLoading) loadNibFile:externalNameTable:withZone:] + 141
12 AppKit 0x00007fff8d9cf514 +[NSBundle(NSNibLoading) loadNibNamed:owner:] + 364
13 AppKit 0x00007fff8dc42355 NSApplicationMain + 398
14 SongViewer 0x0000000100001882 main + 34
15 SongViewer 0x0000000100001854 start + 52
)
2011-08-12 23:13:20.098 SongViewer[2146:707] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSAppleEventDescriptor setSize:]: unrecognized selector sent to instance 0x102827f70'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff86f11986 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff8b04cd5e objc_exception_throw + 43
2 CoreFoundation 0x00007fff86f9d5ae -[NSObject doesNotRecognizeSelector:] + 190
3 CoreFoundation 0x00007fff86efe803 ___forwarding___ + 371
4 CoreFoundation 0x00007fff86efe618 _CF_forwarding_prep_0 + 232
5 SongViewer 0x0000000100002a83 -[IPMenulet awakeFromNib] + 4483
6 CoreFoundation 0x00007fff86f089e1 -[NSObject performSelector:] + 49
7 CoreFoundation 0x00007fff86f08962 -[NSSet makeObjectsPerformSelector:] + 274
8 AppKit 0x00007fff8d9d9c27 -[NSIBObjectData nibInstantiateWithOwner:topLevelObjects:] + 1245
9 AppKit 0x00007fff8d9d01b9 loadNib + 322
10 AppKit 0x00007fff8d9cf6b6 +[NSBundle(NSNibLoading) _loadNibFile:nameTable:withZone:ownerBundle:] + 217
11 AppKit 0x00007fff8d9cf5d1 +[NSBundle(NSNibLoading) loadNibFile:externalNameTable:withZone:] + 141
12 AppKit 0x00007fff8d9cf514 +[NSBundle(NSNibLoading) loadNibNamed:owner:] + 364
13 AppKit 0x00007fff8dc42355 NSApplicationMain + 398
14 SongViewer 0x0000000100001882 main + 34
15 SongViewer 0x0000000100001854 start + 52
)
terminate called throwing an exception(gdb)
If anyone has any idea what could be wrong, please let me know!!
Ok so I figured it out. The solution is to use the NSData raw data provided by the API rather than the NSImage. So I used:
NSImage *songArtwork = [[NSImage alloc] initWithData:[artwork rawData]];
rather than
songArtwork = [artwork data];
I have to fetch batch of track artworks from iTunes and use ‘rawData’ too.
But this way is inefficient.
I found a better way (actually it decreases ‘fetch’ time about 2 times, it’s very significant when fetching artworks for many tracks using ‘valueForKey:’ according to «Improving the Performance of Scripting Bridge Code»).
So I decided to understand what’s wrong with iTunesArtwork ‘data’ property.
We expect to get an NSImage object (according to iTunes.h ), but real object is kind of ‘NSAppleEventDescriptor’. And it’s easy to guess, that this object contains an image for us. So we can just use ‘data’ property to get image data. And this is really faster than getting ‘rawData’ from iTunesArtwork.
But sometimes iTunes return NSImage object instead NSAppleEventDescriptor. This is an strange behavior, but it's still faster then using rawData.

Simple document app, throwing an exception on "revert to saved" in Mac OS X 10.7 Lion

I have a simple document app, based on the document template, which is throwing an exception when the "Revert to Saved -> Last Opened Version" menu item is selected on Mac OS X 10.7.
The exception isn't in my code, it's inside Cocoa. It also doesn't appear to be related to anything I'm doing. My app is very simple (at this stage), almost a vanilla cocoa document based app, based on the template included with the latest stable version of Xcode.
I realise this is probably a bug in Lion, but I need to find a workaround.
See below for the exception, and the entire contents (very small) of my NSDocument subclass.
Steps to reproduce
open any document
type a single character into the text view
select File -> Revert to Saved
click Last Opened Version
Exception
2011-09-04 07:10:29.182 myapp[15433:707] *** -[NSPathStore2 stringByAppendingPathExtension:]: nil argument
2011-09-04 07:10:29.191 myapp[15433:707] (
0 CoreFoundation 0x00007fff89c2b986 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff90c6ed5e objc_exception_throw + 43
2 CoreFoundation 0x00007fff89c2b7ba +[NSException raise:format:arguments:] + 106
3 CoreFoundation 0x00007fff89c2b744 +[NSException raise:format:] + 116
4 Foundation 0x00007fff86d2b172 -[NSPathStore2 stringByAppendingPathExtension:] + 112
5 AppKit 0x00007fff9148f8c3 -[NSDocument _preserveCurrentVersionForReason:error:] + 579
6 AppKit 0x00007fff9147655b __-[NSDocument _revertToVersion:preservingFirst:error:]_block_invoke_3 + 99
7 Foundation 0x00007fff86ef28c3 __-[NSFileCoordinator coordinateReadingItemAtURL:options:error:byAccessor:]_block_invoke_1 + 113
8 Foundation 0x00007fff86ef2f34 -[NSFileCoordinator(NSPrivate) _invokeAccessor:orDont:thenRelinquishAccessClaimForID:] + 202
9 Foundation 0x00007fff86d98a28 -[NSFileCoordinator(NSPrivate) _coordinateReadingItemAtURL:options:error:byAccessor:] + 663
10 Foundation 0x00007fff86ef284c -[NSFileCoordinator coordinateReadingItemAtURL:options:error:byAccessor:] + 79
11 AppKit 0x00007fff91484b41 __-[NSDocument _revertToVersion:preservingFirst:error:]_block_invoke_1 + 347
12 AppKit 0x00007fff914901e3 -[NSDocument performSynchronousFileAccessUsingBlock:] + 42
13 AppKit 0x00007fff9148fc90 -[NSDocument _revertToVersion:preservingFirst:error:] + 125
14 AppKit 0x00007fff91476cf9 -[NSDocument _revertToDiscardRecentChangesPreservingFirst:error:] + 43
15 AppKit 0x00007fff91477094 __-[NSDocument _revertToDiscardRecentChangesThenContinue:]_block_invoke_3 + 164
16 AppKit 0x00007fff91474851 __-[NSDocument performSynchronousFileAccessUsingBlock:]_block_invoke_1 + 19
17 AppKit 0x00007fff91475bda -[NSDocument continueFileAccessUsingBlock:] + 227
18 AppKit 0x00007fff91490413 -[NSDocument _performFileAccessOnMainThread:usingBlock:] + 466
19 AppKit 0x00007fff9149023f -[NSDocument performSynchronousFileAccessUsingBlock:] + 134
20 AppKit 0x00007fff91495891 __-[NSDocument _revertToDiscardRecentChangesThenContinue:]_block_invoke_2 + 301
21 AppKit 0x00007fff914909a9 -[NSDocument _something:wasPresentedWithResult:soContinue:] + 21
22 AppKit 0x00007fff91381bee -[NSAlert didEndAlert:returnCode:contextInfo:] + 93
23 AppKit 0x00007fff9138e356 -[NSApplication endSheet:returnCode:] + 275
24 AppKit 0x00007fff91381ab4 -[NSAlert buttonPressed:] + 265
25 CoreFoundation 0x00007fff89c1b11d -[NSObject performSelector:withObject:] + 61
26 AppKit 0x00007fff911dd852 -[NSApplication sendAction:to:from:] + 139
27 AppKit 0x00007fff911dd784 -[NSControl sendAction:to:] + 88
28 AppKit 0x00007fff911dd6af -[NSCell _sendActionFrom:] + 137
29 AppKit 0x00007fff911dcb7a -[NSCell trackMouse:inRect:ofView:untilMouseUp:] + 2014
30 AppKit 0x00007fff9125c57c -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] + 489
31 AppKit 0x00007fff911db786 -[NSControl mouseDown:] + 786
32 AppKit 0x00007fff911a666e -[NSWindow sendEvent:] + 6280
33 AppKit 0x00007fff9113ef19 -[NSApplication sendEvent:] + 5665
34 AppKit 0x00007fff910d542b -[NSApplication run] + 548
35 AppKit 0x00007fff9135352a NSApplicationMain + 867
36 myapp 0x00000001000018d2 main + 34
37 myapp 0x00000001000018a4 start + 52
)
NSDocument Subclass
#implementation MyTextDocument
#synthesize textStorage;
#synthesize textView;
+ (BOOL)autosavesInPlace
{
return YES;
}
- (id)init
{
self = [super init];
if (self) {
self.textStorage = nil;
self.textView = nil;
textContentToLoad = [#"" retain];
}
return self;
}
- (NSString *)windowNibName
{
return #"MyTextDocument";
}
- (void)windowControllerDidLoadNib:(NSWindowController *)aController
{
[super windowControllerDidLoadNib:aController];
self.textStorage = self.textView.textStorage;
[self loadTextContentIntoStorage];
}
- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError
{
return [self.textStorage.string dataUsingEncoding:NSUTF8StringEncoding];
}
- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError
{
textContentToLoad = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if (!textContentToLoad) {
*outError = [NSError errorWithDomain:NSCocoaErrorDomain code:NSFileReadUnknownError userInfo:nil];
return NO;
}
[self loadTextContentIntoStorage];
return YES;
}
- (void)loadTextContentIntoStorage
{
if (!self.textStorage || !textContentToLoad)
return;
[self.textStorage beginEditing];
[self.textStorage replaceCharactersInRange:NSMakeRange(0, self.textStorage.length) withString:textContentToLoad];
[textContentToLoad release], textContentToLoad = nil;
}
#end
Is your plist set up correctly when it comes to types?
It appears that NSDocument passes the result of [self fileNameExtensionForType:[self autosavingFileType] saveOperation:NSAutosaveElsewhereOperation] to stringByAppendingPathExtension: (the method that's throwing the exception here). If your app returns nil for this expression, then this exception may result.
You should probably file a bug at Apple for this, but in the meantime, make sure your app returns something non-nil.
Paste this into you document class (e.g. Document.m):
-(NSString*)fileNameExtensionForType:(NSString *)typeName saveOperation: (NSSaveOperationType)saveOperation
{
return #"yourAutosaveExtension";
}
Before, like kperryua said, this method was not implemented and returned nil.