Extensions

RSS for tag

Give users access to your app's functionality and content throughout iOS and macOS using extensions.

Posts under Extensions tag

188 Posts
Sort by:
Post not yet marked as solved
0 Replies
3.2k Views
There are many cases where you want to do long-running network operations in a short-lived app extension. For example, you might be creating a share extension that needs to upload a large image to an Internet server. Doing this correctly is quite tricky. The rest of this post describes some of these pitfalls and explains how to get around them. Just by way of context: Most of the following was written during the iOS 8.1 timeframe, although AFAIK there’s been no specific changes in this space since then. The specific focus here is a share extension, although the behaviour is likely to be similar for other short-lived extensions. I wasn’t using SLComposeServiceViewController, although I have no reason to believe that makes a difference. I was testing on a device, not the simulator. In my experience the simulator is much less likely to terminate a share extension, which affects how things behave as I’ll explain later. My app and its share extension have an app group in common. I started by verifying that this app group was working as expected (using UserDefaults). The URLSession must be in that app group; set this via the sharedContainerIdentifier property of the URLSessionConfiguration object you use to create the session. The app and the share extension must use the same URLSession background session identifier (the value you pass in to background(withIdentifier:) when creating the configuration that you use to create the session). When an URLSession background session is shared like this, it’s critical to understand that the session only allows one process to ‘connect’ to it at a time. If a process is connected to the session and another tries to connect, the second process has its session immediately invalidated with NSURLErrorBackgroundSessionInUseByAnotherProcess. The connected session is the one that receives the session’s delegate callbacks. IMPORTANT If callbacks are generated when no process is connected, the background session resumes (or relaunches) the app rather than the extension. If a process is connected to a session and is then suspended or terminates, the session disconnects internally. If the process was terminated, the reconnection happens when your code creates its URLSession object on next launch. If the process was suspended, the reconnect happens when the app is resumed with the application(_:handleEventsForBackgroundURLSession:completionHandler:) delegate callback (and remember that this is always the app, not the extension, per the previous paragraph). The only way to programmatically disconnect from a session is to invalidate it. The expected behaviour here is that the extension will start an URLSession task and then immediately quit (by calling completeRequest(returningItems:completionHandler:)). The system will then resume (or relaunch) the container app to handle any delegate callbacks. When the system resumes or relaunches the container app to handle background session events, it calls application(_:handleEventsForBackgroundURLSession:completionHandler:). The container app is expected to: Save away the completion handler. Reconnect to the session, if necessary. This involves creating the URLSession object if it doesn’t currently exist. Handle delegate events from that session. Invalidate the session when those events are all done. The app knows this because the session calls the urlSessionDidFinishEvents(forBackgroundURLSession:) delegate callback. Call the completion handler that was saved in step 1. This leaves the app disconnected from the session, so future invocations of the extension don’t have to worry about the NSURLErrorBackgroundSessionInUseByAnotherProcess problem I mentioned earlier. This design works best if each extension hosted by the app has its own shared session. If the app hosts multiple extensions, and they all used the same shared session, they could end up stomping on each other. In my tests I’ve noticed that some annoying behaviour falls out of this design: If you start a task from an extension, it’s non-deterministic as to whether the app or extension gets the ‘did complete’ callback. If the task runs super quickly, the extension typically gets the callback. If the task takes longer, the system has time to terminate the extension and the app is resumed to handle it. There’s really no way around this. The workaround is to put the code that handles request completion in both your app and your extension (possibly sharing the code via a framework). It would be nice if the extension could disconnect from the session immediately upon starting its request. Alas, that’s not currently possible (r. 18748008). The only way to programmatically disconnect from the session is to invalidate it, and that either cancels all the running tasks (invalidateAndCancel()) or waits for them to complete (finishTasksAndInvalidate()), neither of which is appropriate. One interesting edge case occurs when the app is in the foreground while the share extension comes up. For example, the app might have a share button, from which the user can invoke the share extension. If the share extension starts an URLSession task in that case, it can result in the app’s application(_:handleEventsForBackgroundURLSession:completionHandler:) callback being called while the app is in the foreground. The app doesn’t need to behave differently in this case, but it’s a little unusual. Xcode’s debugger prevents the system from suspending the process being debugged. So, if you run your extension from Xcode, or you attach to its process some time after launch, the process will continue to execute in situations where the system would otherwise have suspended it. This makes it tricky to investigate problems with the ‘extension was suspended before the network request finished’ case. The best way to investigate any issues you encounter is via logging. Note For more information about debugging problems with background networking, see Testing Background Session Code. Keep in mind that not all networking done by your extension has to use a background session. You should use a background session for long-running requests, but if you have short-running requests then it’s best to run them in a standard session. For example, imagine you have a share extension that needs to make two requests: The first request simply gets an upload authorisation token from the server. This request is expected to finish very quickly. The second request actually uploads the file (including the upload authorisation token from the previous request), and is expected to take a long time. It makes sense to only use a background session for the second request. The first request, being short-running, can be done in a standard session, and that will definitely simplify your code. When doing this you have to prevent your extension from suspending while the short-lived request is in flight. You can use ProcessInfo.performExpiringActivity(withReason:using:) for this. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" Revision History 2023-08-30 Fixed the formatting. Adopted Swift terminology throughout. Made other minor editorial changes. 2017-04-26 Moved to the new DevForums. Made many editorial changes. Added the section on Xcode’s debugger. Added a section on short-running network requests. 2014-12-05 First posted on the old DevForums.
Posted
by
Post not yet marked as solved
11 Replies
8.3k Views
I'm unable to share UserDefaults with the same suiteName with newly announced iOS 14 widgetkit extension (It constantly returns nil). Is there anything that I should do apart from having same suite name for this to work? Thanks!
Posted
by
Post marked as solved
2 Replies
2.1k Views
I am writing a keyboard-extension, there are several buttons and these buttons have a text, therefor I am using localized strings. So the extension is always in the "correct" language. When opening the keyboard-extension with the "world"-button (pressing it long, so that the menu is shown) there is always a line below the name of the app showing "English". As far as I know this is the primary language, there is also one entry for "PrimaryLanguage" in the info.plist (NSExtension/NSExtensionAttributes, set to "en-US"). I tried to remove this entry, but after this the app does not start anymore. Is there a different way to remove this entry or is it possible to change it to the language of the localization?
Posted
by
Post not yet marked as solved
3 Replies
1.7k Views
runtime.oninstalled is invoked when I install the extension for the first time in the browser. But if I uninstalled it again (by dragging the app to bin), and tried reinstalling the runtime.oninstalled is not invoked. is that an expected behavior? If so, how can I test this case during extension development? Because it is difficult to find a new browser to test this case every time. Thanks.
Posted
by
Post not yet marked as solved
3 Replies
1.8k Views
I am creating in the application support for the Unwanted Communication Reporting extension. All I found is this guide from Apple: https://developer.apple.com/documentation/sms_and_call_reporting/sms_and_call_spam_reporting and i follow it. I've done: Instantiates my ViewController from ILClassificationUIExtensionViewController. Calls controller’s prepare(for:) method to customize UI. Create button to notify the system when you have completed gathering information (setting setting isReadyForClassificationResponse property to true.) Configure classificationResponse(for:) method after pressing Done button. I want to send a response over the network so I add an associated domain to extension by following this instruction: https://developer.apple.com/documentation/xcode/supporting-associated-domain and advises from interenet.  Create file apple-app-site-association, use classificationreport instead of webcredentials when specifying the domains. {  "applinks": {   "apps": [],   "details": [    {     "appID": “XXXX.com.project.UnwantedCommunicationExtension",     "paths": ["*"]    }   ]  },  "classificationreport": {    "apps": ["XXXX.com.project.UnwantedCommunicationExtension"]   } } Add domain to the entitlement: Specify the network endpoint’s address using the ILClassificationExtensionNetworkReportDestination key in extension’s Info.plist file: Create test server and sent the apple-app-site-association file to this server.  Debugging and proxying my app, it doesn’t send any requests to the server. I can’t find any information about what request type should be sent, what data type will the server receive. Can anyone help to find information about it? Maybe advice what I did wrong, what settings should be on the server?
Posted
by
Post not yet marked as solved
4 Replies
1.4k Views
Hi! Does anybody encountered a problem when selected custom keyboard disappears from keyboards list after updating to iOS 15? We have a lot of complaints from our users, once a day they need to go to Settings to re-add our keyboard extension. FB9700027 in case someone from Apple can take a look. Thanks!
Posted
by
Post not yet marked as solved
6 Replies
5.7k Views
Issue Summary Hi all, I'm working on an Intents Extension for my app, however when I try to run an intent, Xcode pops up the following error: Could not attach to pid: "965" attach failed (Not allowed to attach to process. Look in the console messages (Console.app), near the debugserver entries, when the attach failed. The subsystem that denied the attach permission will likely have logged an informative message about why it was denied.) An image of the error: This only happens when I try debugging the Intent Extension. Running the main app target or another extension target (e.g. notifications) doesn't produce this error. Build Setup Here are the details of my build setup: Mac Mini M1 Xcode 13 Building to iPhone 11 Pro Max, iOS 15.0.2. I've also tried building to my iPad Pro 12.9 w/ iOS 15.1 and hit the same issue. Things I've tried: Make sure "Debug executable" is unchecked in the scheme I've tried changing the Launch setting to "Automatic" and "Wait for the executable to be launched" I've made sure to run sudo DevToolsSecurity -enable on my mac Rebooted iPhone devices + mac mini Uninstalled / reinstalled the app Deleted derived data Removing / reinstalling the development certs in my keychain --> this actually seemed to work initially, but then the problem came back and now it doesn't work anymore. Console Logs I've looked at the console logs while this error occurs to see if it can shed light on the issue. Here are the ones that seemed notable to me. These logs seem to show that Siri is trying to save / write to a file that it does not have access too. Seems very suspicious error 11:42:38.341470-0800 kernel System Policy: assistantd(31) deny(1) file-read-metadata /private/var/mobile/Library/com.apple.siri.inference error 11:42:38.342204-0800 assistantd failed to save contact runtime data. error=Error Domain=NSCocoaErrorDomain Code=512 "The file “com.apple.siri.inference” couldn’t be saved in the folder “Library”." UserInfo={NSFilePath=/var/mobile/Library/com.apple.siri.inference, NSUnderlyingError=0x100fb03a0 {Error Domain=NSPOSIXErrorDomain Code=5 "Input/output error"}} error 11:42:38.342403-0800 assistantd InferenceError<errorId=crSaveToRunTimeDBFailed file=/Library/Caches/com.apple.xbs/Sources/SiriInference/SiriInference-3100.49.3.1.2/SiriInference/SiriInference/ContactResolver/ContactResolver.swift function=logRunTimeData(runTimeData:config:) line=378 msg=> error 11:42:38.465702-0800 kernel 1 duplicate report for System Policy: assistantd(31) deny(1) file-read-metadata /private/var/mobile/Library/com.apple.siri.inference Looking for "debugserver" entries, like the error suggests, shows these logs: default 11:42:44.814362-0800 debugserver error: [LaunchAttach] MachTask::TaskPortForProcessID task_for_pid(965) failed: ::task_for_pid ( target_tport = 0x0203, pid = 965, &task ) => err = 0x00000005 ((os/kern) failure) default 11:42:44.814476-0800 debugserver 10 +0.011525 sec [03c6/0103]: error: ::task_for_pid ( target_tport = 0x0203, pid = 965, &task ) => err = 0x00000005 ((os/kern) failure) err = ::task_for_pid ( target_tport = 0x0203, pid = 965, &task ) => err = 0x00000005 ((os/kern) failure) (0x00000005) default 11:42:44.825704-0800 debugserver error: MachTask::StartExceptionThread (): task invalid, exception thread start failed. default 11:42:44.825918-0800 debugserver error: [LaunchAttach] END (966) MachProcess::AttachForDebug failed to start exception thread attaching to pid 965: unable to start the exception thread default 11:42:44.826025-0800 debugserver error: Attach failed default 11:42:44.828923-0800 debugserver error: Attach failed: "Not allowed to attach to process. Look in the console messages (Console.app), near the debugserver entries, when the attach failed. The subsystem that denied the attach permission will likely have logged an informative message about why it was denied.". I've also attached the full details of the error below via a text file if it helps. Any help with this issue would be great, and I'm happy to provide more information if needed. Thanks in advance! Xcode Attach Full Error Details
Posted
by
Post not yet marked as solved
3 Replies
2k Views
Hi. I implemented a broadcast upload extension and it requests local notifications. The local notification works normally on broadcastStarted(withSetupInfo:), but the Banner of the local notification does not work on processSampleBuffer(_: with:) though its Notification Center works normally. What am I missing? Here is my code snippets. container app class AppDelegate: NSObject, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. requestAuthorization() ... } private func requestAuthorization() { let center = UNUserNotificationCenter.current() center.requestAuthorization(options: [.alert]) { granted, error in if let error = error { // Handle the error here. print(error) } if granted == true { center.delegate = self center.getNotificationSettings(completionHandler: { setting in print(setting) }) } else { print("not permitted") } } } } upload extension class SampleHandler: RPBroadcastSampleHandler { override func broadcastStarted(withSetupInfo setupInfo: [String : NSObject]?) { super.broadcastStarted(withSetupInfo: setupInfo) notification(title: "Upload Extension", body: "broadcastStarted") ... } override func processSampleBuffer(_ sampleBuffer: CMSampleBuffer, with sampleBufferType: RPSampleBufferType) { super.processSampleBuffer(sampleBuffer, with: sampleBufferType) ... if some condition { notification(title: "Upload Extension", body: "processSampleBuffer") } } private func notification(title: String, body: String) { let content = UNMutableNotificationContent() content.title = title content.body = body let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: nil) let notificationCenter = UNUserNotificationCenter.current() notificationCenter.add(request) { error in if error != nil { print(error) } } } }
Posted
by
Post not yet marked as solved
1 Replies
1.7k Views
I've developed a ios safari web extension for my app and everything seemed to work fine in the simulator and on my device. However, I've noticed that in some cases when the user tries to give permission to the extension inside safari, the system displays an alert asking for permissions to all the sites saved in the user's keychain. It's really strange. I've not been able to always reproduce this behavior, sometimes it works normally and it asks for permission just for the domain where the user is on. The issue has become a real problem when I've discovered that when the user has a lot of saved passwords for sites in the keychain, the Safari freezes when asking for permission and becomes absolutely unusable, forcing the user to close it. Here is the manifest for my extension: { "manifest_version": 2, "content_security_policy": "script-src 'self' https://ssl.google-analytics.com; object-src 'self'", "background": { "scripts": [ "browser-polyfill.js", "background.js" ], "persistent": false }, "content_scripts": [{ "js": [ "browser-polyfill.js", "document-start.js" ], "matches": [ "http://*/*", "https://*/*" ], "run_at": "document_start" }, { "js": [ "browser-polyfill.js", "contentscript.js" ], "matches": [ "http://*/*", "https://*/*" ], "run_at": "document_idle" } ], "browser_action": { "default_icon": { "19": "assets/images/logos/16x16_logo.png", "38": "assets/images/logos/48x48_logo.png", "48": "assets/images/logos/48x48_logo.png", "64": "assets/images/logos/64x64_logo.png", "128": "assets/images/logos/128x128_logo.png", "256": "assets/images/logos/256x256_logo.png", "512": "assets/images/logos/512x512_logo.png" }, "default_popup": "popup.html" }, "icons": { "16": "assets/images/logos/16x16_logo.png", "48": "assets/images/logos/48x48_logo.png", "64": "assets/images/logos/64x64_logo.png", "128": "assets/images/logos/128x128_logo.png", "256": "assets/images/logos/256x256_logo.png", "512": "assets/images/logos/512x512_logo.png" }, "web_accessible_resources": [ "assets/*" ], "permissions": [ "<all_urls>", "cookies", "storage", "unlimitedStorage", "webNavigation", "notifications", "nativeMessaging" ] } Here is the screenshot of the safari asking for permission to the extension to access 653 different websites that are registered in the user's keychain:
Posted
by
Post not yet marked as solved
3 Replies
1.3k Views
I am trying to write a safari web extension that redirects users to Y URL if they type X URL without ever loading the X URL. The piece of code that I have attached below works smoothly on chrome, but not on safari. background.js function onBeforeNavigate(event) { const redirectURL = "https://google.com/" chrome.tabs.update(event.tabId, { url: redirectURL }) } chrome.webNavigation.onBeforeNavigate.addListener(onBeforeNavigate,{ url: [ {urlMatches: "https://girlcodeit.com/*"}, {urlMatches: "http://girlcodeit.com/*"} ] }) manifest.json "manifest_version": 2, "name": "", "description": "", "version": "1.0", "background": { "scripts": [ "background.js" ] }, "permissions": [ "webNavigation", "tabs" ] } I have tried writing browser.tabs.update and just tabs.update in place of chrome.tabs.update in safari version, no change. I want to achieve the redirection anyhow through a safari web extension, please suggest changes in this one or share any other approaches. webRequestBlocking is not supported by Safari, so that doesn't work either.
Posted
by
Post marked as solved
2 Replies
1.9k Views
I have a macOS Share Extension invoked when users tap the Share button in Safari. I'm trying to get the page's URL from the -[NSExtensionItem attachments] attribute, but it comes as an NSSecureCoding object, and I'm unable to read the URL from it. In the loadView method, I'm filtering and loading the attachments of type public.url: override func loadView() { super.loadView() guard let inputItem = extensionContext?.inputItems.first as? NSExtensionItem else { print("Didn't received input item from action.") return } var itemProvider: NSItemProvider? itemProvider = inputItem.attachments?.filter({ $0.registeredTypeIdentifiers.contains("public.url") }).first ?? inputItem.attachments?.filter({ $0.registeredTypeIdentifiers.contains("public.plain-text") }).first guard let itemProvider = itemProvider else { print("Didn't received attachments from input item.") return } if itemProvider.canLoadObject(ofClass: URL.self) { itemProvider.loadItem(forTypeIdentifier: "public.url", completionHandler: onLoadVideoURL) } else if itemProvider.canLoadObject(ofClass: String.self) { itemProvider.loadItem(forTypeIdentifier: "public.plain-text", completionHandler: onLoadVideoURL) } else { print("This action only supports URL and String.") } } The itemProvider.loadItem method runs for the type identifier public.url, calling the completion handler bellow: @objc private func onLoadVideoURL(dict: NSSecureCoding?, error: Error?) { print("URL: \(dict.debugDescription)") // ... } But the content that it prints to the console is: URL: Optional(<68747470 733a2f2f 73746163 6b6f7665 72666c6f 772e636f 6d2f7175 65737469 6f6e732f 35323231 39373030 2f686f77 2d746f2d 63617374 2d6e7373 65637572 65636f64 696e672d 746f2d6d 6b6d6170 6974656d 2d696e2d 61637469 6f6e2d65 7874656e 73696f6e>) The same code works as expected on iOS, printing the shared URL to the console. Do I have to somehow convert this NSSecureCoding to URL or another object? Or should I do this in a completely different way on macOS? The goal is to access the page's URL from the Share Extension activated when the user selects it in the Share Menu.
Posted
by
Post not yet marked as solved
3 Replies
2.1k Views
I have an app which uses the Call Directory Extension to identify callers. It has been downloaded a few hundred times and a small percentage of users are reporting this error. They are logged in to the app but when they go to phone -> settings -> call blocking & identification they get one of two error messages. "An error occurred while attempting to enable app." "Failed to request data for app. You may try enabling the extension again and if the problem persists contact the application developer." I'm not sure how this could be an issue with the app because it works for the majority of users. Furthermore users still experience the error when I ask them to log in with a test account. One user even reported that they could enable it in settings but a little while later it will disable itself. I have seen similar posts where it's been suggested that the error may be due to bad data (out of order, duplicate contacts, etc) but this error shows before the app even begins to load the data. Does anyone know under what conditions this error popup shows? Many thanks
Posted
by
Post not yet marked as solved
1 Replies
773 Views
I'm working on an "Issuer Provisioning" extension for iOS. Instances of my root PKIssuerProvisioningExtensionHandler subclass are initialised and reinitialised often (every time the user taps the "+" button in the Wallet app) and live for a few milliseconds. So far, so good. The head-scratching part is that the extensions' process lives on across multiple invocations. This in turn has the effect that static member values also live on, meaning they are not in a predictable state during instantiation. Some of my static-loving dependencies are unhappy with this pattern. Is this "process outliving instances" extension pattern a common one? Is it described anywhere? Can it be disabled?
Posted
by
Post not yet marked as solved
1 Replies
1.2k Views
Hi all. My app has a custom keyboard extension and I am trying to figure out a way to differentiate between a user manually exiting my keyboard vs the entire keyboard being collapsed or hidden. My problem is specifically on on iPhones >= X aka models that do not have a home button. The viewWillDisappear lifecycle method is great for handling both of the above. But I need a way to separate them. I have my own button that advances to the next input which I can account for (green circle). What I do not know how to account for is the user pressing Apple's globe icon to advance to the next input (red circle). Does anyone know a way to react to a user pressing the globe icon/a generic way to know if the user has switched keyboards as opposed to the keyboard going away.
Posted
by
Post not yet marked as solved
3 Replies
2.0k Views
So I've been trying to debug / read console.logs from background scripts when using manifest v3 but it never fires any log. It works well in manifest v2 though. I have set the persmission and host_permission as well changed my background to service_work in manifest but nothing really happens: "background": { "service_worker": "scripts/background.js" }, My Qyestion is, is it currently possible to use manifest v3 on iOS safari web extension? Some Notes: Reading this page: https://developer.apple.com/documentation/safariservices/safari_web_extensions/assessing_your_safari_web_extension_s_browser_compatibility It says: "background: In iOS, you must set the persistent attribute to false. With manifest version 3, all background pages are nonpersistent." So I'm guessing it is somehow possible to use right?
Posted
by
Post not yet marked as solved
4 Replies
2.8k Views
I have a working Chrome extension using manifest version 3, and I am following the porting instructions to turn it into a Safari extension on MacOS (Monterey) - using xcrun from the Xcode toolset. I have Safari v. 15.5. There are two problems. First, the documentation says "Safari 15.4 and later supports manifest versions 2 and 3". So how come xcrun complains about all of the following keys: manifest_version, icons, description, version, js, matches, service_worker, type, action, tabs, activeTab, storage, alarms, webNavigation, web_accessible_resources, name, css? At least some of those are basic to v3 manifests. Second, when I try to install it in Safari (it builds OK under Xcode despite the above "problem") I get an error. In my background (service worker) script I call self.importScripts("Platform.js"); which should load said JavaScript file. It's in the same folder as the script that calls it. This works in Chrome but fails in Safari with the error: Failed to load resource: unsupported URL safari-web-extension://FE580C4D-9931-4639-ABF9-...../Platform.js I tried changing that dynamic import to a static import: import Platform from "./Platform.mjs"; (After converting Platform.js to a module Platform.mjs.) This also works on chrome but now my converted extension for Safari won't even load. I get: The service_worker script failed to load due to an error. But I can find no way of determining what that error is (there is no information in the service worker console). I would appreciate help with either or both of these problems. Perhaps they are connected and there is something missing/wrong about my version 3 manifest - even though Chrome is happy with it.
Posted
by
Post not yet marked as solved
2 Replies
1.2k Views
I am putting a stand-alone iMessage extension sticker pack together and can't seem to get my icons to display when I run on my physical device. I have followed every thread and ran the gamut on the different solutions. I am still lost with this one and need some help. I am attaching some screenshots of how they display on my physical devices. My code runs great and I do not get any build errors. to my knowledge (and I'm a newbie): All icon assets have been correctly sized and attributed to the correct targets Target memberships have been correctly attributed as well From the Info.plist I have deleted the CFBundleicons~ipad and Icon files (iOS 5) as per recommendations from previous solutions. (I tried running with and without these auto attributional add ons) deleted or not, still doesn't solve the issues. Thanks in advance, hopefully, it helps me and others in the future :) Ps. I didn't want to flood the post with too many screenshots, but if there is anything you need to see to help me solve this one, let me know and I'll try to follow up.
Posted
by
Post not yet marked as solved
2 Replies
1.7k Views
I have a chrome extension that was converted to Safari extension using xcode safari-web-extension-converter utility. With that, everything except one thing seems to be fine. In the background script, I am loading some data from a web accessible resource like so: export const fetchConfig = async () => { let dataURL = ''; if (!checkBrowser(BROWSERS.Chrome, true)) { dataURL = chrome.runtime.getURL('config.json'); } else { dataURL = browser.runtime.getURL('config.json'); } const res = await fetch(dataURL); return await res.json(); } This works for all browsers except Safari. Where I am getting the runtime URL as: safari-web-extension://E522689D-94A6-4561-90F3-BF22C7848965/config.json but the fetch call fails with the error: Failed to load resource: unsupported URL I have not been able to find anything on this in the documentation, but can we not access the web accessible resources in background in Safari? My manifest file looks like this: { "manifest_version": 3, "name": "Ext Dev", "author": "Test", "description": "Test", "version": "1.1.0", "icons": { "16": "assets/icon/icon16.png", "32": "assets/icon/icon32.png", "48": "assets/icon/icon48.png", "128": "assets/icon/icon128.png" }, "host_permissions": [ ... host addresses here ... ], "permissions": ["storage", "tabs"], "content_security_policy": { "extension_pages": "script-src 'self'; object-src 'self';" }, "web_accessible_resources": [{ "resources": ["config.json"], "matches": ["<all_urls>"] }], "content_scripts": [ { "matches": ["<all_urls>"], "js": ["content.js"], "css": ["commonstyles.css"], "run_at": "document_end", "all_frames": true } ], "background": { "service_worker": "background.js" }, "action": { "default_title": "Ext Client", "default_icon": { "20": "assets/icon/icon20.png", "40": "assets/icon/icon40.png" } }
Posted
by
Post marked as solved
4 Replies
2.4k Views
Hi there, I have two extension in my App, a Finder Sync and a Share Extension. Because these are disabled by default and automatically enabling them is, according to my extensive research, not possible, I want to provide an easy way for the user to enable the extensions when the app is opened. I am currently displaying a popup, with a button to open the preferences. I have struggled with this a bit, by now I managed to open the main preferences window using NSWorkspace.shared.open(URL(string: "x-apple.systempreferences:com.apple.preference")!) which is rather suboptimal though, since the user has to select the extensions option manually and isn't directly redirected there. What I have also found is that the menu of the FinderSyncExtension can be opened directly by using FIFinderSyncController.showExtensionManagementInterface() which is unfortunately suboptimal as well, because it only shows the managment interface of the finder extension and not the overview of all extensions. Is there any way to either enable the extensions programatically, or if not, is there a way to show the "Added Extensions" portion of the Extensions menu in the system preferences?
Posted
by
Post marked as solved
15 Replies
5.1k Views
I am playing around with Live Activities and got everything working on the iOS 16.1 beta 2 simulator using Xcode 14.1 beta 2 (14B5024i). However, running the same code on a real physical device (iPhone X) running iOS 16.1 beta 2 does not show the Live Activity on the lock screen at all. 😵 Did anyone get their Live Activity working on a real device yet, or is this an issue with the current beta? Things I have already checked: ActivityAuthorizationInfo().areActivitiesEnabled returns true on my physical device let activity = try Activity.request(...) successfully completes without throwing and I can see the activity.id printed to the console Other live activities - such as the iOS system timer activity - do show up on my physical device just fine
Posted
by