I recently tried converting an Objective-C project to Swift using Swiftify.
The project has been successfully converted and there are no errors/warning but on running the project the application shows a black screen.
The errors in the console are:
Info.plist configuration "Default Configuration" for UIWindowSceneSessionRoleApplication contained UISceneDelegateClassName key, but could not load class with name "SceneDelegate".
and
There is no scene delegate set. A scene delegate class must be specified to use the main storyboard file.
But as it can be seen from my Project hierarchy there is a SceneDelegate class present.
Also the contents of my Info.plist file is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>SceneDelegate</string>
<key>UISceneStoryboardFile</key>
<string>Main</string>
</dict>
</array>
</dict>
</dict>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>
Also please review the screen recording here.
Also here is the link of the project.
The problem is this pair of lines in the Info.plist:
<key>UISceneDelegateClassName</key>
<string>SceneDelegate</string>
The issue is that you think "SceneDelegate" is the name of the SceneDelegate class, but Objective-C does not think so! You have to write:
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
Try to configure your window scene like this:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
window?.makeKeyAndVisible()
let controller = YoursatrtController() // your start controller class name
window?.rootViewController = controller
}
Related
I'm trying to use the iOS 14 initForOpeningContentTypes: rather than the deprecated initWithDocumentTypes:inMode: and I'm unable to get access to files with the extension p8 (they are greyed out).
I'm trying the following code:
NSArray<UTType*> * contentTypes = #[[UTType typeWithFilenameExtension: #"p8"
conformingToType: UTTypeData]];
UIDocumentPickerViewController *documentPicker = nil;
documentPicker = [[UIDocumentPickerViewController alloc] initForOpeningContentTypes: contentTypes];
The picker launches, but the file "myfile.p8" is greyed out and unselectable. What am I doing wrong here?
Once I added the following to my application’s Info.plist I was able to select the file:
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeIdentifier</key>
<string>com.my-company.my-identifier</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeDescription</key>
<string>My Description</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>p8</string>
</array>
</dict>
</dict>
</array>
Apparently it tells the system about the type. See this answer for info about UTExportedTypeDeclarations.
I am creating a cordova plugin to upload images to s3.
When I build the project I get the following error:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'The service configuration is `nil`. You need to configure `Info.plist` or set `defaultServiceConfiguration` before using this method.'
I have followed other answers on here and added the extra keys to the info.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIcons~ipad</key>
<dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>icon-small</string>
<string>icon-40</string>
<string>icon-50</string>
<string>icon-76</string>
<string>icon-72</string>
<string>icon</string>
</array>
</dict>
</dict>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>4.28.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>0.0.1</string>
<key>Fabric</key>
<dict>
<key>APIKey</key>
<string></string>
<key>Kits</key>
<array>
<dict>
<key>KitInfo</key>
<dict/>
<key>KitName</key>
<string>Crashlytics</string>
</dict>
</array>
</dict>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>DynamoDBObjectMapper</key>
<dict>
<key>Default</key>
<dict>
<key>Region</key>
<string>eu-west-1</string>
</dict>
</dict>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>amazonaws.com</key>
<dict>
<key>NSThirdPartyExceptionMinimumTLSVersion</key>
<string>TLSv1.0</string>
<key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
<key>amazonaws.com.cn</key>
<dict>
<key>NSThirdPartyExceptionMinimumTLSVersion</key>
<string>TLSv1.0</string>
<key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
<key>localhost</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSLocationUsageDescription</key>
<string>Geolocation information is used to tag assessments and assessment contents with the users location. This is only used when conducting an assessment.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Geolocation information is used to tag assessments and assessment contents with the users location. This is only used when conducting an assessment.</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UIRequiresFullScreen</key>
<true/>
<key>UIStatusBarHidden~ipad</key>
<true/>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
<key>AWS</key>
<dict>
<key>S3TransferManager</key>
<dict>
<key>Default</key>
<dict>
<key>Region</key>
<string>eu-west-1</string>
</dict>
</dict>
</dict>
</dict>
</plist>
This is the function in the plugin.
- (void)uploadImage:(CDVInvokedUrlCommand*)command
{
AWSS3TransferManager *transferManager = [AWSS3TransferManager defaultS3TransferManager];
NSString* filePath = [command argumentAtIndex:0 withDefault:nil];
NSURL *uploadingFileURL = [NSURL fileURLWithPath: filePath];
AWSS3TransferManagerUploadRequest *uploadRequest = [AWSS3TransferManagerUploadRequest new];
uploadRequest.bucket = #"my-test-bucket";
uploadRequest.key = #"mykey";
uploadRequest.body = uploadingFileURL;
[[transferManager upload:uploadRequest] continueWithExecutor:[AWSExecutor mainThreadExecutor]
withBlock:^id(AWSTask *task) {
if (task.error) {
if ([task.error.domain isEqualToString:AWSS3TransferManagerErrorDomain]) {
switch (task.error.code) {
case AWSS3TransferManagerErrorCancelled:
case AWSS3TransferManagerErrorPaused:
break;
default:
NSLog(#"Error: %#", task.error);
break;
}
} else {
// Unknown error.
NSLog(#"Error: %#", task.error);
}
}
if (task.result) {
AWSS3TransferManagerUploadOutput *uploadOutput = task.result;
// The file uploaded successfully.
}
return nil;
}];
}
The exception is thrown at line:
AWSS3TransferManager *transferManager = [AWSS3TransferManager defaultS3TransferManager];
I found a solution using the answer provided in https://stackoverflow.com/a/39957439/3191747
Adding the following to didFinishLaunchingWithOptions in the AppDelegate solved the problem:
AWSStaticCredentialsProvider *credentialsProvider = [[AWSStaticCredentialsProvider alloc] initWithAccessKey:AWS_ACCESS_KEY secretKey:AWS_SECRET_KEY];
AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionAPSoutheast1
credentialsProvider:credentialsProvider];
AWSServiceManager.defaultServiceManager.defaultServiceConfiguration = configuration;
Using Xcode, is it possible to create an Objective-C or C single-file tool (i.e, no app bundle) that handles a custom URL schema?
I've added -sectcreate __TEXT __info_plist Info.plist_path into my other linker flags and below is my info.plist that is supposed to be added to the binary (not sure how I can confirm that is is being added). But, building the binary doesn't result in myCoolURLHandler://key=value being handled by the new tool.
I've very new to objective-c and Xcode, so I am sure I am missing something.
My info.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>Apple.${PRODUCT_NAME:rfc1034identifier}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleVersion</key>
<string>0.1</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>URLHandlerTestApp</string>
<key>CFBundleURLSchemes</key>
<array>
<string>myCoolURLHandler</string>
</array>
</dict>
</array>
</dict>
</plist>
I'm trying to add UTI for a pair of file types, matching by extension. I think I've got it setup properly - at the very least, the file extension -> UTI mapping is recognized (I declared it as an imported type in info.plist). However, when I try to get the UTI off of my test file, I get back a dynamic UTI. Here's the sample code I'm using to test these two cases:
NSString *previewTypeUTI = nil;
NSURL *previewFileURL = [NSURL fileURLWithPath:#"/Users/eblair/Desktop/EWF/thetestfile.myext1"];
[previewFileURL getResourceValue:&previewTypeUTI forKey:NSURLTypeIdentifierKey error:nil];
NSLog(#"%#", previewTypeUTI); // #1
NSString *testUTI = (NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (CFStringRef)[previewFileURL pathExtension], NULL);
NSLog(#"%#", testUTI); // #2
[testUTI release];
NSLog #1 prints out "dyn.########" and NSLog #2 prints out "com.mycompany.filetype1". I would've expected them to print the same thing. Is there some extra step to get the file->UTI mapping working or is it a case of Launch Services needing to catch up?
Just using the extension->UTI mapping isn't an option because I want to use some APIs that take advantage of UTIs and those APIs seem to be using the file->UTI mapping.
For the sake of completeness, here's the plist entry for the imported types:
<key>UTImportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.disk-image</string>
</array>
<key>UTTypeDescription</key>
<string>File Type 1</string>
<key>UTTypeIdentifier</key>
<string>com.mycompany.filetype1</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>myext1</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.disk-image</string>
</array>
<key>UTTypeDescription</key>
<string>File Type 2</string>
<key>UTTypeIdentifier</key>
<string>com.mycompany.filetype2</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>myext2</string>
</array>
</dict>
</dict>
</array>
Well, it's been close to a year, but I had to re-address this today and I think I stumbled across what I did wrong. It looks like you need to include public.data as a type you conform to, even though public.disk-image already conforms to public.data. So, the UTTypeConformsTo array should look like this:
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
<string>public.disk-image</string>
</array>
After making this change, my above comparison of the file->UTI and extension->UTI now yield the same result.
How do you set your Cocoa application as the default web browser?
I want to create an application that is launched by default when the user clicks on an HTTP or HTTPS link in other applications (Mail, iChat etc.).
There are four steps to making an app that can act as the default web browser. The first three steps allow your app to act as a role handler for the relevant URL schemes (HTTP and HTTPS) and the final step makes it the default role handler for those schemes.
1) Add the URL schemes your app can handle to your application's info.plist file
To add support for http:// and https:// you'd need to add the following to your application's info.plist file. This tells the OS that your application is capable of handling HTTP and HTTP URLs.
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>http URL</string>
<key>CFBundleURLSchemes</key>
<array>
<string>http</string>
</array>
</dict>
<dict>
<key>CFBundleURLName</key>
<string>Secure http URL</string>
<key>CFBundleURLSchemes</key>
<array>
<string>https</string>
</array>
</dict>
</array>
2) Write an URL handler method
This method will be called by the OS when it wants to use your application to open a URL. It doesn't matter which object you add this method to, that'll be explicitly passed to the Event Manager in the next step. The URL handler method should look something like this:
- (void)getUrl:(NSAppleEventDescriptor *)event
withReplyEvent:(NSAppleEventDescriptor *)replyEvent
{
// Get the URL
NSString *urlStr = [[event paramDescriptorForKeyword:keyDirectObject]
stringValue];
//TODO: Your custom URL handling code here
}
3) Register the URL handler method
Next, tell the event manager which object and method to call when it wants to use your app to load an URL. In the code here I'm passed self as the event handler, assuming that we're calling setEventHandler from the same object that defines the getUrl:withReplyEvent: method.
You should add this code somewhere in your application's initialisation code.
NSAppleEventManager *em = [NSAppleEventManager sharedAppleEventManager];
[em
setEventHandler:self
andSelector:#selector(getUrl:withReplyEvent:)
forEventClass:kInternetEventClass
andEventID:kAEGetURL];
Some applications, including early versions of Adobe AIR, use the alternative WWW!/OURL AppleEvent to request that an application opens URLs, so to be compatible with those applications you should also add the following:
[em
setEventHandler:self
andSelector:#selector(getUrl:withReplyEvent:)
forEventClass:'WWW!'
andEventID:'OURL'];
4) Set your app as the default browser
Everything we've done so far as told the OS that your application is a browser, now we need to make it the default browser.
We've got to use the Launch Services API to do this. In this case we're setting our app to be the default role handler for HTTP and HTTPS links:
CFStringRef bundleID = (CFStringRef)[[NSBundle mainBundle] bundleIdentifier];
OSStatus httpResult = LSSetDefaultHandlerForURLScheme(CFSTR("http"), bundleID);
OSStatus httpsResult = LSSetDefaultHandlerForURLScheme(CFSTR("https"), bundleID);
//TODO: Check httpResult and httpsResult for errors
(It's probably best to ask the user's permission before changing their default browser.)
Custom URL schemes
It's worth noting that you can also use these same steps to handle your own custom URL schemes. If you're creating a custom URL scheme it's a good idea to base it on your app's bundle identifier to avoid clashes with other apps. So if your bundle ID is com.example.MyApp you should consider using x-com-example-myapp:// URLs.
macOS Big Sur and Up
Copy and paste this code into your info.plist
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>Web site URL</string>
<key>CFBundleURLSchemes</key>
<array>
<string>http</string>
<string>https</string>
</array>
</dict>
<dict>
<key>CFBundleURLName</key>
<string>http URL</string>
<key>CFBundleURLSchemes</key>
<array>
<string>http</string>
</array>
</dict>
<dict>
<key>CFBundleURLName</key>
<string>Secure http URL</string>
<key>CFBundleURLSchemes</key>
<array>
<string>https</string>
</array>
</dict>
<dict>
<key>CFBundleTypeName</key>
<string>HTML document</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>public.html</string>
</array>
</dict>
<dict>
<key>CFBundleTypeName</key>
<string>XHTML document</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>public.xhtml</string>
</array>
</dict>
</array>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeIconFile</key>
<string>document.icns</string>
<key>CFBundleTypeName</key>
<string>GIF image</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>com.compuserve.gif</string>
</array>
</dict>
<dict>
<key>CFBundleTypeIconFile</key>
<string>document.icns</string>
<key>CFBundleTypeName</key>
<string>HTML document</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>public.html</string>
</array>
</dict>
<dict>
<key>CFBundleTypeIconFile</key>
<string>document.icns</string>
<key>CFBundleTypeName</key>
<string>XHTML document</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>public.xhtml</string>
</array>
</dict>
<dict>
<key>CFBundleTypeIconFile</key>
<string>document.icns</string>
<key>CFBundleTypeName</key>
<string>JavaScript script</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>com.netscape.javascript-source</string>
</array>
</dict>
<dict>
<key>CFBundleTypeIconFile</key>
<string>document.icns</string>
<key>CFBundleTypeName</key>
<string>JPEG image</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>public.jpeg</string>
</array>
</dict>
<dict>
<key>CFBundleTypeIconFile</key>
<string>document.icns</string>
<key>CFBundleTypeName</key>
<string>MHTML document</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>org.ietf.mhtml</string>
</array>
</dict>
<dict>
<key>CFBundleTypeIconFile</key>
<string>document.icns</string>
<key>CFBundleTypeName</key>
<string>HTML5 Audio (Ogg)</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>org.xiph.ogg-audio</string>
</array>
</dict>
<dict>
<key>CFBundleTypeIconFile</key>
<string>document.icns</string>
<key>CFBundleTypeName</key>
<string>HTML5 Video (Ogg)</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>org.xiph.ogv</string>
</array>
</dict>
<dict>
<key>CFBundleTypeIconFile</key>
<string>document.icns</string>
<key>CFBundleTypeName</key>
<string>PNG image</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>public.png</string>
</array>
</dict>
<dict>
<key>CFBundleTypeIconFile</key>
<string>document.icns</string>
<key>CFBundleTypeName</key>
<string>SVG document</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>public.svg-image</string>
</array>
</dict>
<dict>
<key>CFBundleTypeIconFile</key>
<string>document.icns</string>
<key>CFBundleTypeName</key>
<string>Plain text document</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>public.text</string>
</array>
</dict>
<dict>
<key>CFBundleTypeIconFile</key>
<string>document.icns</string>
<key>CFBundleTypeName</key>
<string>HTML5 Video (WebM)</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>org.webmproject.webm</string>
</array>
</dict>
<dict>
<key>CFBundleTypeIconFile</key>
<string>document.icns</string>
<key>CFBundleTypeName</key>
<string>WebP image</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>org.webmproject.webp</string>
</array>
</dict>
<dict>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>org.chromium.extension</string>
</array>
</dict>
<dict>
<key>CFBundleTypeIconFile</key>
<string>document.icns</string>
<key>CFBundleTypeName</key>
<string>PDF Document</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>com.adobe.pdf</string>
</array>
</dict>
</array>
Your app will be shown in the system preferences and will be default browser
Make sure you do this
func application(_ application: NSApplication, open urls: [URL]) {
// do a for loop, I recommend it
}
If you just want to change the default helper app for http(s), you can do so in the Safari preferences. There you’ll find a drop down which will let you select all the registered handler applications for http. To automatically have the app set itself as the default browser see the previous instructions.
In order to appear as an option on System Preferences > General > Default web browser (at least for macOS 11) you need to add the document types for HTML and XHTML to the Info.plist (after the 4 steps already described on the accepted answer), like this:
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeName</key>
<string>HTML document</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>public.html</string>
</array>
</dict>
<dict>
<key>CFBundleTypeName</key>
<string>XHTML document</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>public.xhtml</string>
</array>
</dict>
</array>