12

In my objective-c program, I need to open a URL in Safari no matter what the system's default browser is. That means that this won't work, because it could launch Firefox or whatever other browser:

NSWorkspace * ws = [NSWorkspace sharedWorkspace];
[ws openURL: url];

I think I'm close with this:

[ws launchAppWithBundleIdentifier: @"com.apple.Safari"
                          options: NSWorkspaceLaunchWithoutActivation
   additionalEventParamDescriptor: NULL
                 launchIdentifier: nil];

only need to figure out how to pass in the URL as parameter... Is there an easier way?

Thanks!

Update: The following code launches Safari with the URL I want, but Safari terminates right away! Any ideas why this is?

NSWorkspace * ws = [NSWorkspace sharedWorkspace];
[ws openURLs: urls withAppBundleIdentifier:@"com.apple.Safari" 
     options: NSWorkspaceLaunchDefault
additionalEventParamDescriptor: NULL
launchIdentifiers: NULL];

I observed the same behavior with LSOpenFromURLSpec. If a Safari instance is running, it works fine. If no Safari instance was running, it starts a new one and terminates it right away.

Update 2: Safari only crashes for web sites that have Flash embedded. With the code above, I can open google.com just fine, however Safari crashes for a YouTube video, for example.

Mike Abdullah
  • 14,933
  • 2
  • 50
  • 75
Mark
  • 343
  • 1
  • 4
  • 13
  • 'system("Safari URL")' or something similar doesn't work? –  Jun 03 '10 at 14:19
  • Unfortunately no. I tried this from the Terminal. Safari starts up, but treats the URL as local file and thus can't find it. – Mark Jun 04 '10 at 04:50
  • This got me close, but if Safari is not already running, it opens and terminates right away. No error reported: NSString *safariFullPath = [[NSWorkspace sharedWorkspace] fullPathForApplication:@"Safari"]; NSArray* urls = [ NSArray arrayWithObject: url]; LSLaunchURLSpec urlSpec; urlSpec.appURL = (CFURLRef)[NSURL URLWithString:safariFullPath]; urlSpec.itemURLs = ( CFArrayRef )urls; urlSpec.passThruParams = NULL; urlSpec.launchFlags = kLSLaunchAsync; urlSpec.asyncRefCon = NULL; OSStatus status = LSOpenFromURLSpec( &urlSpec, NULL ); – Mark Jun 04 '10 at 05:26
  • @Mark This throws - +[__NSCFConstantString baseURL]: unrecognized selector sent to class 0x7fff9805b1b8 – mirap May 01 '17 at 19:21

4 Answers4

5

Try the OpenURLs method from NSWorkspace:

- (BOOL) openURLs:(NSArray *)urls
         withAppBundleIdentifier:(NSString *)bundleIdentifier
         options:(NSWorkspaceLaunchOptions)options
         additionalEventParamDescriptor:(NSAppleEventDescriptor *)descriptor
         launchIdentifiers:(NSArray **)identifiers
Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
Jon Shier
  • 12,200
  • 3
  • 35
  • 37
3

Use this to open the url in the default browser...

NSURL *url = [NSURL URLWithString:@"http://www.stackoverflow.com/"];
if( ![[NSWorkspace sharedWorkspace] openURL:url] )
    NSLog(@"Failed to open url: %@",[url description]);
rogers
  • 366
  • 2
  • 10
2

The two options I listed above actually work for websites that don't include Flash movies.

The crash I described seems to be a bug that can even be reproduced with a single Applescript. I opened a separate question for this (AppleScript to open URL in Safari crashes for Flash-based websites)

For the record, the answer to my question is to either use LSOpenFromURLSpec or this code:

NSWorkspace * ws = [NSWorkspace sharedWorkspace];
[ws openURLs: urls withAppBundleIdentifier:@"com.apple.Safari" 
  options: NSWorkspaceLaunchDefault
  additionalEventParamDescriptor: NULL
  launchIdentifiers: NULL];
Community
  • 1
  • 1
Mark
  • 343
  • 1
  • 4
  • 13
  • Hy Mark, if this solved your problem now. You may want to mark your (or another one) as the answer to your question. If you experience a crash I think this would be another issue then. – Besi Mar 25 '15 at 10:44
  • How do it on iOS? NSWorkspace available just for macOS 10.0+ – Anonimys Dec 03 '20 at 08:36
2

You don't need an AppKit framework. Just implement this.

NSURL *url = [NSURL URLWithString:@"http://www.apple.com"];    

[[UIApplication sharedApplication] openURL:url];
Undo
  • 25,519
  • 37
  • 106
  • 129