How do I disable automatic text replacement in my NSTextViews? - macos

Our app has some non-rich-text NSTextViews that users can enter text into. When a user enters "..." into the text view, OS X automatically replaces it with an ellipsis character, which we don't want to happen. This needs to be something we disable for all users of our app, rather than relying on them to disable it themselves.
I expected this to be an NSUserDefaults setting, like the "ApplePressAndHoldEnabled" one, but I was unable to find anything in the docs about it. I found some information about the "WebAutomaticTextReplacementEnabled" preference that sounds like it does what we need, but setting it to "NO" doesn't seem to do anything for our app.
I've also looked at NSSpellChecker, which appears to provide the "isAutomaticTextReplacementEnabled" method to check whether text replacement happens, but no way to stop it happening for an application.
How can I disable this text replacement for our app?

There are settings in the nib file for this (select the NSTextView). Unfortunately as of the latest version of OS X / Xcode, some of them seem to be broken so you may find that you have to send messages to your view from e.g. -awakeFromNib instead, e.g.
- (void)awakeFromNib
{
[myTextView setAutomaticQuoteSubstitutionEnabled:NO];
[myTextView setAutomaticTextReplacementEnabled:NO];
}
See the documentation for NSTextView for the full set of methods.

Related

UI XCTest recording with unicode characters in XCode 7 gives wrong Swift code

Right now when recording an element on my app, it returns something along the lines of:
XCUIApplication().alerts["\U201cMy Application\U201d Would Like to Send You Notifications"].staticTexts["Notifications may include alerts, sounds, and icon badges. These can be configured in Settings."].tap()
Which throws a compiler error. I then changed it to this, to follow the swift convention on references unicode characters:
XCUIApplication().alerts["\u{201c}My Application\u{201d} Would Like to Send You Notifications"].staticTexts["Notifications may include alerts, sounds, and icon badges. These can be configured in Settings."].tap()
This does compile, but the test fails because Swift does not find the element when testing. I then tried this:
XCUIApplication().alerts["“My Application” Would Like to Send You Notifications"].staticTexts["Notifications may include alerts, sounds, and icon badges. These can be configured in Settings."].tap()
Which has the same result.
I realize that this is likely a bug with xcode, but is there a workaround? The issue seems to have been around for awhile.
I can't reproduce your error. Using the swift convention \u{201c}works great. U can also try using just a backslash if you want to use quotation marks
"\"MyApp\" Would Like to Send You Notifications"
You message indicates that you want to react to a system notification rather than your own UIAlert. Thats why you can't find it. Try setting up an UI Interuption Alert before the Alert appears and then react to it:
addUIInterruptionMonitorWithDescription("\"MyApp\" Would Like to Send You Notifications") {
(alert) -> Bool in
alert.buttons["OK"].tap()
return true
}
Also consider Joe Masilotti's excellent Cheat Sheet for further information.
Workaround for Xcode 7.1 bug in UI XCTest recording unicode titles (Swift)
Record all actions you want as usual.
Copy generated code
Open this online unicode converter tool
Paste your code in "Unicode characters*" text area
Select conversion direction: Unicode characters to unicode escape sequences
Click Convert button
Copy converted code from "Unicode escape sequences" text area in your program
That all. I hope Apple will fix this bug soon.
I faced the same problem and I fixed it with this code below:
let notificationAlertElement = XCUIApplication().alerts["\u{201c}My Application\u{201d} Would Like to Send You Notifications"].staticTexts["Notifications may include alerts, sounds, and icon badges. These can be configured in Settings."].collectionViews.buttons["OK"]
if (notificationAlertElement.exists) {
notificationAlertElement.tap()
}
I can't get "addUIInterruptionMonitorWithDescription" working. So, the solution I use is to not register for notification if in simulator.
//Because simulator does not have to have notifications, ust disable it.
#if !arch(i386) && !arch(x86_64)
//Ask the user to accept notifications from the application
application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: UIUserNotificationType.Alert, categories: nil))
#endif

How to register a custom non-document UTI / file type for OSX to recognize it?

I've read all the tickets about this issue, but I still don't get it right. I have a non-document OSX app (for OSX Lion and MountainLion). I want this app to export and import custom data, associated with a custom file extension ".iobs". Internally, these files are just data archived with [NSKeyedArchiver archivedDataWithRootObject:], and saved onto the disk with the "iobs" extension.
So, my check list is this:
1) Export mechanism: checked. My app create correctly .iobs files. If I run "file <filename.iobs>" in the Terminal, I get "iObserve_exportedItems.iobs: Apple binary property list"
2) Declaration of an exported UTI, checked. As shown in the image below. I did NOT declared a custom Document type, since it I never use NSDocument inside my app, and there is no point. Anyway, I already tried and failed. I've tried also different combinations of "Conforms To" entries, but with no success.
3) Is there any 3rd point??? Do I need to start my app once to let the system know? I just ran it in Debug from Xcode so far, and this has no effect. So I guess my Info.plist is wrong, but I filled it from within Xcode4 interface, so???
Thanks for any help, hint, question, suggestion.
Ok, so apparently, I do have to declare a document type even if I don't specify a document class. See the attached screenshot. Note that leaving only the Document UTI doesn't work. I do need the two (exported UTI and document type). Note also that if I say it conforms to com.apple.binary-property-list, I don't have the right icon.
And for those who wonder, there is nothing to do to "register" a type (and its subsequent changes) apart from launching the app once.

Problems with implementing Versions

I try to implement Versions in application that already written for Snow Leopard. It is an Document based application with SQLite storage. Each document saves as an SQLite db file.
I have implemented appropriate methods in my NSPersistentDocument subclass:
+ (BOOL)autosavesInPlace {return YES;}
+ (BOOL)preservesVersions {return YES;}
Now I have new File menu in application with "Save a Version" etc. I create new document in my app, save it, make some changes, save again.. When I entering version browser I get:
kCGErrorFailure: CGSDisplayID: App trying to enumerate [0 to CGSGetNumberOfDisplays()] instead of using CGSGetDisplayList(). Compensating...
kCGErrorFailure: Set a breakpoint # CGErrorBreakpoint() to catch errors as they are logged.
In right side of version browser in list of versions I see few versions, but they do not displayed in stack of windows. It looks like windows are in stack but completely transparent. When I clicks on any version in list I get log:
CoreData: error: (8) attempt to write a readonly database
Than if I tried to restore one of versions - version browser normally closed, no window appears and program stops responding.
I can't understand what it all can means. Is it problem in saving version or in restoring? I just have no ideas. Will be grateful for any help.
Each Core Data store is already stored on disk when the versions browser is opened. Have you looked at your overrides for creating the document, and for reading them? Are you sure none of them also edit the document? You might also want to check your awakeFromNib methods, to see that you are not writing / saving anything to a new document.
It can be difficult to debug problems when leaving the version browser. To make it easier, you can edit your current scheme, select the 'Options' tab, and check 'Enable debugging in "Browse all versions" mode'.

Dropping Files onto Dock Icon in Cocoa

How can I drop a file(or select to open it in Finder) of a type specified in the Info.plist onto my dock icon and then calling a method with the full path of the file?
If you've set up your Info.plist's CFBundleDocumentTypes array properly (either 'LSItemContentTypes' or 'CFBundleTypeExtensions'), then you just need to set up an NSApplication delegate and implement the delegate method, application:openFile:.
If you're expecting multiple files to be dropped at once, implement application:openFiles:.
For promised files (NSFilesPromisePboardType/kPasteboardTypeFileURLPromise) see Dropping promised files on to application icon in Dock.
Here's an updated solution for Xcode 5.
In AppDelegate.m
-(BOOL)application:(NSApplication *)sender openFile:(NSString *)filename
{
NSLog(#"%#", filename);
return YES;
}
And in Xcode setup Document Types under Project > Targets > Info:
Check settings in Info.plist in case you have an empty 'Document Content Type UTIs' array which should be filled out properly or else deleted.
Your Info.plist should look something like this:
On current systems you can use a UTI instead of the old-style four-char types (such as fold above). In Xcode's document type editor, make a new type with:
Name: Folder
Identifier: public.folder
public.folder is a subtype of public.directory. public.folder matches directories that appear as such to the user, i.e. not packages like .app wrappers.
Select your application in the target group of the side pane and use get info. Then in the new window select the properties tab to add a new document type. Name it "Folder" for convenience and the OS Types needs to be "fold"; the store type and role you can leave as is.
If you're actually making a document-based app, setting it up to give you the path will have you doing far more work than you need to. Simply use the document-based application template. The document controller will create an instance of the right class for you; you need only write that class.
An application you create this way will handle file drops (by opening them as documents) for free.

Macintosh C Creating a navigation window to choose an app

I'm writing a C program for mac, and I need to allow the user to choose an application to send an apple event to. I can create a navigation window, using NavCreateChooseFileDialog(), but I can't get it to enable any .app files. If I restrict the types using NavDialogSetFilterTypeIdentifiers, it will only allow me to select applications like MS Office, that don't have .app in the folder name. Everything else is greyed out.
Any ideas?
Make sure to set the flag kNavSupportPackages in inOptions.optionFlags for NavCreateChooseFileDialog, and put 'APPL' in the types list (might as well still use that param instead of NavDialogSetFilterTypeIdentifiers(), that way you'll run on 10.3-) and you should be good to go, I just tried.
Alternatively, if you don't mind using Cocoa, you can use -[NSOpenPanel runModalForTypes:[NSArray arrayWithObjects:#"app", nil]] (which also lists non-.app applications), and then you're only one FSPathMakeRef((UInt8*)[path fileSystemRepresentation], &fsRef, NULL); away from an FSRef.
Do remember that, in either case, the file you get may be an alias so you will have to try and resolve aliases.
Remember that .app bundles are directories, so you may need to enable some sort of allow-directories (or, more likely, enable-bundles) option.
I'm sorry that I can't offer more specific help. I started with Carbon, but never did touch Navigation Services.
This works for me:
NSOpenPanel * panel = [ NSOpenPanel openPanel ] ;
panel.allowedFileTypes = #[ (__bridge id)kUTTypeApplication ] ;
[ panel runModal ] ;

Resources