Prefill email content with NSButton hyperlink - macos

I was wondering how I could, or if it's even possible to, prefill an email message's content when you click an NSButton, so far I open up the default email client but I want to prefill the body of the email and was wondering how I'd do that. Below is the current code:
-(IBAction)openEmail:(id)sender {
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:#"mailto:domain#domain.com"]];
}

The "mailto" URI scheme supports this: http://en.wikipedia.org/wiki/Mailto
Send email

Rather than forcing a user out of your app, why don't you use MFMailComposeViewController to present the standard message composition window?
MFMailComposeViewController conveniently also has methods to set the message body and just about anything else you would like.
UPDATE: Oops, I misread "NSButton" as "UIButton" - what I wrote above only applies to iOS. Using the mailto: additions is the correct approach AFAIK on OS X.

Related

Hyperlinks in JSQMessagesViewController messages

I'm using the JSQMessages framework which is super awesome but I'm trying to enable hyperlinks in both the sent and received text messages - essentially i want to apply a find and replace system where certain words are replaced with pre determined hyperlinks, for example the word "stackoverflow" would turn into a hyperlink to stackoverflow when the user presses the send message button. The message receiver would then receive the hyperlink.
I have the find and replace system working fine however I'm struggling with the hyperlinks. As far as I can tell there doesn't seem to be any way to add hyperlinks to the messages as the "text" message element used to pass execute the message is an NSString and therefore cannot have a url attributed to it. However I hope I'm wrong, are hyperlinks, i.e. a word that links/executes a url when it's tapped, in text messages possible? If so what would be the recommended approach?
Thanks,
Matt
And for Swift 2.0 :
let attributes: [String:AnyObject] = [NSForegroundColorAttributeName:UIColor.redColor(), NSUnderlineStyleAttributeName: 1]
cell.textView!.linkTextAttributes = attributes
Please use following code in collectionView cellForItemAtIndexPath
Activate the data indicator as well..
cell.textView.dataDetectorTypes=UIDataDetectorTypeAll;
cell.textView.linkTextAttributes = #{ NSForegroundColorAttributeName : [UIColor jsq_messageBubbleBlueColor],
NSUnderlineStyleAttributeName : #(NSUnderlineStyleNone | NSUnderlineStyleNone) };

TouchID: What's the difference between fallback (enter password) and cancel?

I'm integrating TouchID into my app, but I don't get the difference between the two buttons enter password and cancel. They result in an error of LAErrorUserCancel or LAErrorUserFallback, but I can't handle them differently, so I'd like to avoid one of the two buttons. Is there a way to do this? Or what's the best practice here?
1Password is an example here; both buttons the user gets presented are leading to the same action - that you have to enter the password into the app manually. In my opinion it would make sense to have only one button here.
It is super easy to remove the "Enter Password" button if you don't need it for your application. Just set the localizedFallbackTitle property to an empty string, not nil, and the button will not be display.
LAContext *context = [[LAContext alloc] init];
context.localizedFallbackTitle = #"";
(You can't also set it to something more appropriate for your application if you need to, just put the string in there.)
Note: to actually answer the question as posted, not to answer the comment that that OP left on the other answer... the fallback case is useful when the user has decided to not use TouchID but would rather enter a password to gain access to your locked service. You would test for this in the evaluatePolicy message.
If the touchID alert view is displayed from the same VC that contains the password field, both options would accomplish the same. But think in cases where you have workflow where you can cancel the full authentication operation (LAErrorUserCancel) or display a login view controller(LAErrorUserFallback).

What is the purpose of the NSMenuItem's tag attribute?

Can I use the item's tag attribute to store a special key/ID or is it meant for something else?
Example of intended use:
- (void)awakeFromNib {
[self.popup addItemWithTitle: [NSString stringWithFormat: #"dummy title" ]];
[[self.popup lastItem] setTag: 1658 ];
}
- (IBAction)popupAction: (id)sender {
[self someMethod: [sender selectedItem].tag];
}
yeah the tag of all controls is free for your devious use, you may use different numbers for different items, or to identify them as a kind of item, it is up to you.
As the documentation says:
You typically assign tags to menu items from Interface Builder, but you can also assign them programmatically using the setTag: method of NSMenuItem.
For further details, read the Application Menus and Pop-Up Lists and User Interface Validation guides. But the basic idea is that Cocoa doesn't care what you put there.
I believe the intended purpose is to let you loosely couple parts of your code together—the code that validates user actions doesn't have to know how your interface is designed, and your interface doesn't have to know anything about the validator; they just have to agree on a number. However, in modern Cocoa, it's just as easy, and even more loose, to just look at the action, so the tag is freed up for anything you want.

Programmatically launching OS X's Contacts app showing a contact?

Let's say that I've just created an ABPerson record and managed to save it in the user's address book. How do I programmatically open the default application which handles the address book (which most likely is Contacts but in some cases it might be Outlook or some other app) and show the new address book record I've just added?
Thanks in advance.
The addressbook URL scheme is able to show the person record or edit it:
ABPerson * aPerson = <#assume this exists#>;
// Open the Contacts app, showing the person record.
NSString * urlString = [NSString stringWithFormat:#"addressbook://%#", [aPerson uniqueId]];
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:urlString]];
More information is in Address Book Programming Guide.
Here is my take using the Contacts app, and in Swift, written as an extension for CNContact. I expect most people are using Contacts in preference to AddressBook nowadays.
(CNContact's identifier is the same as ABPerson's uniqueId.)
func showInContacts() {
let path =
"/Users/someusername/Library/Application Support/AddressBook/Sources/05A62A31-9C1F-423F-A9F4-011E56EAAF29/Metadata/0A1F4FC2-7E01-4A40-92DE-840F8C84DE58:ABPerson.abcdp
var url = URL(fileURLWithPath: path)
url.deleteLastPathComponent()
url.appendPathComponent(self.identifier)// self is a CNContact
url.appendPathExtension("abcdp")
NSWorkspace.shared.open(url)
}
Contacts are in separate files buried at the end of a long chain of sub-folders in user's Library/Application Support. The file names are simply the contact's identifier plus an extension. You can save some typing by dragging one of them to your Xcode editor, surrounding with quotes, and maybe removing the last path component. As my app isn't for distribution that is enough for me; otherwise you will have to do some doctoring: the user's name will be in the second path component. I don't know the significance of the long ID number following 'Sources', whether it is user or system specific, but it is the only item in that subfolder, so you should be able to build a viable path programatically.

NSNotificationCenter in document-based app

I'm using NSNotificationCenter to send custom notifications in a document-based app.
A document-based app can have many open documents. Ideally, I would like the the document and its children to receive only the notifications created within the document or its children. In other words, a document should receive only the notifications that the same document generates.
At first I thought I could use the notificationSender parameter of addObserver:selector:name:object: but then I realised that I don't always know which object will send the notification.
Do I have to check if I'm in the right document for every custom notification? Is there a better way to do this?
I think that your approach works if you use the main document as notificationSender argument for both addObserver:selector:name:object: and postNotificationName:object:.
You can define a NotificationCenter in your NSDocument class and use that to post notifications within a document (Swift):
class Document: NSDocument {
let notificationCenter = NotificationCenter()
// Other stuff
}
And call it like this:
document.notificationCenter.post(name: yourNotificationIdentifier, object: nil)

Resources