Extensions

RSS for tag

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

Posts under Extensions tag

200 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

Wallet UI extension with capacitor
Hello, I'm trying to build a wallet UI extension for card push provisioning of Apple Pay. I try to add a user authentication step to the wallet app extension. I went through the documentations and app demo, but all the guidelines are based on swift UI, while I want to reuse the code from my Angular containing app (html, css, typescript) compiled to iOS native app with capacitor. Does anyone have any experience how this can be done? Do I need to separate the authentication logic in my Angular project and compile it to a separate iOS native app using capacitor? Thank you in advance.
1
1
376
Jul ’24
Media Extension API - How to properly vend GOP samples from a MediaFormat Extension
Hello I am testing the new Media Extension API in macOS 15 Beta 4. Firstly, THANK YOU FOR THIS API!!!!!! This is going to be huge for the video ecosystem on the platform. Seriously! My understanding is that to support custom container formats you make a MEFormatReader extension, and to support a specific custom codec, you create a MEVideoDecoder for that codec. Ok - I have followed the docs - esp the inline header info and have gotten quite far A Host App which hosts my Media Extenion (MKV files) A Extension Bundle which exposes the UTTYpes it supports to the system and plugin class ID as per the docs Entitlements as per docs I'm building debug - but I have a valid Developer ID / Account associated in Teams in Xcode My Plugin is visible to the Media Extension System preference My Plugin is properly initialized, I get the MEByteReader and can read container level metadata in callbacks I can instantiate my tracks readers, and validate the tracks level information and provide the callbacks I can instantiate my sample cursors, and respond to seek requests for samples for the track in question Now, here is where I get hit some issues. My format reader is leveraging FFMPEGs libavformat library, and I am testing with MKV files which host AVC1 h264 samples, which should be decodable as I understand it out of the box from VideoToolbox (ie, I do not need a separate MEVideoDecoder plugin to handle this format). Here is my CMFormatDescription which I vend from my MKV parser to AVFoundation via the track reader Made Format Description: <CMVideoFormatDescription 0x11f005680 [0x1f7d62220]> { mediaType:'vide' mediaSubType:'avc1' mediaSpecific: { codecType: 'avc1' dimensions: 1920 x 1080 } extensions: {(null)} } My MESampleCursor implementation implements all of the callbacks - and some of the 'optional' sample cursor location methods: (im only sharing the optional ones here) - (MESampleLocation * _Nullable) sampleLocationReturningError:(NSError *__autoreleasing _Nullable * _Nullable) error - (MESampleCursorChunk * _Nullable) chunkDetailsReturningError:(NSError *__autoreleasing _Nullable * _Nullable) error I also populate the AVSampleCursorSyncInfo and AVSampleCursorDependencyInfo structs per each AVPacket* I decode from libavformat Now my issue: I get these log files in my host app: <<<< VRP >>>> figVideoRenderPipelineSetProperty signalled err=-12852 (kFigRenderPipelineError_InvalidParameter) (sample attachment collector not enabled) at FigStandardVideoRenderPipeline.c:2231 <<<< VideoMentor >>>> videoMentorDependencyStateCopyCursorForDecodeWalk signalled err=-12836 (kVideoMentorUnexpectedSituationErr) (Node not found for target cursor -- it should have been created during videoMentorDependencyStateAddSamplesToGraph) at VideoMentor.c:4982 <<<< VideoMentor >>>> videoMentorThreadCreateSampleBuffer signalled err=-12841 (err) (FigSampleGeneratorCreateSampleBufferAtCursor failed) at VideoMentor.c:3960 <<<< VideoMentor >>>> videoMentorThreadCreateSampleBuffer signalled err=-12841 (err) (FigSampleGeneratorCreateSampleBufferAtCursor failed) at VideoMentor.c:3960 Which I presume is telling me I am not providing the GOP or dependency metadata correctly to the plugin. I've included console logs from my extension and host app: LibAVExtension system logs And my SampleCursor implementation is here https://github.com/vade/FFMPEGMediaExtension/blob/main/LibAVExtension/LibAVSampleCursor.m Any guidance is very helpful. Thank you!
1
1
735
Aug ’24
FCP plugin crashes when launching its app
I'm developing a workflow extension for Final Cut Pro, but I'm encountering a setback. For some reason, the extension crashes if I launch the app that contains the plugin. I already added some logic to prevent the app from launching if one is already running, but that didn't fix the issue because the plugin crashes while the app is still loading. It seems to me that the plugin process is being killed while the app is loading, causing the plugin to crash. Do you know why this is happening and how to solve it?
5
1
492
Aug ’24
Its not possible to use a Contact Provider Extension from within a Notification Service Extension
A Notification Service Extension is one of the more capable extensions, and there's a lot that can be done within it (for example, it can invoke a Call Extension). However its not possible to use a Contact Provider Extension within it. If a CPE has been enabled by the main app, then if a push is sent to the NSE, then within the NSE the ContactProviderManager class reports that the CPE is disabled and its not possible to anything with it. For example a call to ContactProviderManager.signalEnumerator() will hang and not complete. I was hoping to create a contact and make it available to the system on receipt of a push, but this isn't going to possible. Is this intentional and by design, or just due to the immaturity of this feature/iOS beta? The documentation of a Contact provider Extension says: "signalEnumerator() An example of using this call is to handle a push notification to your app when the provided contacts from your server update" It therefore seems strange that the main cited use case for ContactProviderManager.signalEnumerator() isn't actually possible if the push is delivered to an extension rather than the app.
3
0
503
Aug ’24
start live activity via push notification pushToStartTokenUpdates
I have success with starting live activity from the server but I have some questions and problem first I get pushToStartTokenUpdates only once what if my user missed it? so I could not start from the server pushToStartTokenUpdates how long I can use? will it refresh the new token? for start live activity via push notification? does token I get from pushToStartTokenUpdates use for only start live activity event from server and can't use for update ? so if token get from pushToStartTokenUpdates for only start live activity via remote so how can I obtain the token for update ?
0
0
387
Jul ’24
Lagging Video Feed Using VNGeneratePersonSegmentationRequest in macOS Camera Extension App
I'm developing a macOS application using Swift and a camera extension. I'm utilizing the Vision framework's VNGeneratePersonSegmentationRequest to apply a background blur effect. However, I'm experiencing significant lag in the video feed. I've tried optimizing the request, but the issue persists. Could anyone provide insights or suggestions on how to resolve this lagging issue? Details: Platform: macOS Language: Swift Framework: Vision code snippet I am using are below `class ViewController: NSViewController, AVCaptureVideoDataOutputSampleBufferDelegate { var frameCounter = 0 let frameSkipRate = 2 private let visionQueue = DispatchQueue(label: "com.example.visionQueue") func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) { frameCounter += 1 if frameCounter % frameSkipRate != 0 { return } guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return } let ciImage = CIImage(cvPixelBuffer: pixelBuffer) performPersonSegmentation(on: ciImage) { [self] mask in guard let mask = mask else { return } let blurredBackground = self.applyBlur(to: ciImage) let resultImage = self.composeImage(with: blurredBackground, mask: mask, original: ciImage) let nsImage = ciImageToNSImage(ciImage: resultImage) DispatchQueue.main.async { [self] in // Update your NSImageView or other UI elements with the composite image if needToStream { if (enqueued == false || readyToEnqueue == true), let queue = self.sinkQueue { enqueued = true readyToEnqueue = false if let _ = image, let cgImage = nsImage.cgImage(forProposedRect: nil, context: nil, hints: nil) { enqueue(queue, cgImage) } } } } } } private func performPersonSegmentation(on image: CIImage, completion: @escaping (CIImage?) -> Void) { let request = VNGeneratePersonSegmentationRequest() request.qualityLevel = .fast // Adjust quality level as needed request.outputPixelFormat = kCVPixelFormatType_OneComponent8 let handler = VNImageRequestHandler(ciImage: image, options: [:]) visionQueue.async { do { try handler.perform([request]) guard let result = request.results?.first as? VNPixelBufferObservation else { completion(nil) return } let maskPixelBuffer = result.pixelBuffer let maskImage = CIImage(cvPixelBuffer: maskPixelBuffer) completion(maskImage) } catch { print("Error performing segmentation: \(error)") completion(nil) } } } private func composeImage(with blurredBackground: CIImage, mask: CIImage, original: CIImage) -> CIImage { // Invert the mask to blur the background let invertedMask = mask.applyingFilter("CIColorInvert") // Ensure mask is correctly resized to match original image let resizedMask = invertedMask.transformed(by: CGAffineTransform(scaleX: original.extent.width / invertedMask.extent.width, y: original.extent.height / invertedMask.extent.height)) // Blend the images using the mask let blendFilter = CIFilter(name: "CIBlendWithMask")! blendFilter.setValue(blurredBackground, forKey: kCIInputImageKey) blendFilter.setValue(original, forKey: kCIInputBackgroundImageKey) blendFilter.setValue(resizedMask, forKey: kCIInputMaskImageKey) return blendFilter.outputImage ?? original } private func ciImageToNSImage(ciImage: CIImage) -> NSImage { let cgImage = context.createCGImage(ciImage, from: ciImage.extent)! return NSImage(cgImage: cgImage, size: ciImage.extent.size) } private func applyBlur(to image: CIImage) -> CIImage { let blurFilter = CIFilter.gaussianBlur() blurFilter.inputImage = image blurFilter.radius = 7.0 // Adjust the blur radius as needed return blurFilter.outputImage ?? image } }`
3
0
374
Jul ’24
How to send x,y data from HIDStylusDriver to StylusApp to Pen/Draw
Here is project I am researching: https://developer.apple.com/documentation/hiddriverkit/handling_stylus_input_from_a_human_interface_device I have a Touch screen and I want: can control this screen, I can enable extension and control Touch screen successfully. can pen on this screen. To do this, I need to send X,Y to StylusApp(AppKit) But I Can not send X, Y to Swift StylusApp Eventhough I can log X,Y it by default code: But I don't know how to send it to AppKit to Pen. I have research about communicate Driver and Client: https://developer.apple.com/documentation/driverkit/communicating_between_a_driverkit_extension_and_a_client_app#4324306 but seem HID driver don't support inheritance from IOUserClient:
3
0
537
Jul ’24
Extensions in Web Apps?
Testing Sequoia public beta. The latest Safari should now support Extensions in web apps. https://developer.apple.com/documentation/safari-release-notes/safari-18-release-notes#Safari-Extensions But even I have extensions in the main Safari, there is none showing up in any of the web apps. What can be done to resolve this?
1
0
368
Jul ’24
sourceAppIdentifier is getting wrong with Sequoia Beta3
HI, I have Mac Sequoia Beta3. I installed Content Filer network extension which is same as https://developer.apple.com/documentation/networkextension/filtering_network_traffic in my machine. When I try to connect a machine through "ssh", NEFilterFlow.description in handleNewFlow(_ flow: NEFilterFlow) is showing "sourceAppIdentifier" (process name) as "Terminal" instead of "ssh". But other Mac OS versions, it is showing as "ssh". Is there any issue with Sequoia Beta3? or Is this expected? Thanks
1
0
372
Jul ’24
Notification Service Extension is initialized but never triggered
Hi all, I'm attempting to implement a notification service extension for my app, however I'm running into some troubles with triggering the extension. The service extension is successfully installed with the app, and is initialized when a notification is received (which ive confirmed by attaching a debugger to it), however the didReceive method is never called. In the debugger console, the following message is printed: Service extension base class recieved didReceiveNotificationRequest: . I can confirm that the all the payload requirements are met to trigger the extension, and I was able to create an extension that would trigger in a blank application (using the same payload). It's only this app that prints this message to the console, and does not trigger. The extension code is as follows (I've removed all of the intended functionality at this point to try and pinpoint the issue) class NotificationService: UNNotificationServiceExtension { var contentHandler: ((UNNotificationContent) -> Void)? var bestAttemptContent: UNMutableNotificationContent? override init() { self.contentHandler = nil self.bestAttemptContent = nil print("startup!") } func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) async { let logger = Logger(subsystem: "app.revolt.chat", category: "notificationservice") logger.info("Invoked notification extension") debugPrint(request) self.contentHandler = contentHandler bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) guard let bestAttemptContent = bestAttemptContent else { print("content is null") return } bestAttemptContent.title = "beans" if request.content.categoryIdentifier != "ALERT_MESSAGE" { bestAttemptContent.subtitle = "not an alert message" contentHandler(bestAttemptContent) return } contentHandler(bestAttemptContent) } override func serviceExtensionTimeWillExpire() { // Called just before the extension will be terminated by the system. // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used. if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent { contentHandler(bestAttemptContent) } } }
0
1
439
Jul ’24
Share arbitrary struct from HostApp to Extension and get arbitrary result back
I want to share a Transferable (JSON-encoded) data struct from some HostApp with an Extension of my ContainingApp, and get a different Transferable (also JSON-encoded) data struct back on success. Since I want to present my ContainingApp's AppIcon in the sharing sheet to make it easy for the user to find it, I started building a Sharing Extension and not an Action Extension. AFAIK the difference is only in the presentation (Sharing Extension: Icon+name of the ContainingApp vs Action Extension: simple b/w system icon plus a string describing the action (e.g. "Copy", "Save to Files")), and the data flow is identical. Please correct me if I'm wrong. I added the Sharing Extension to my ContainingApp (which are both in the same app group so they can use a shared container to exchange data). The (real) HostApp is from a different company we are collaborating with, and thus is not in our app group. Once everything runs I will add a tailored NSExtensionActivationRule to make sure our Sharing Extension is only shown to our partner's HostApp. Currently I am still using TRUEPREDICATE. The goal is that after the user tapped the "Continue with ContainingApp" (Share-)button in the HostApp, iOS will only show my ContainingApp icon and nothing else, since that's the only useful choice for the user. Side Question 1: The best user experience would be if the HostApp could directly present our extension when the user tapped the "Continue with ContainingApp"-button, without the user needing to choose it manually in the Share-sheet, but I guess this is not possible for privacy/security reasons, right? In the debugger of the HostApp I see this error: Type "com.myapp.shareInput" was expected to be exported in the Info.plist of Host.app, but it was imported instead. Library: UniformTypeIdentifiers | Subsystem: com.apple.runtime-issues | Category: Type Declaration Issues but I definitely want to define and export both ShareInput and ShareResult as UTExportedTypeDeclarations in my extension, and all 3rd-party apps (like this demo HostApp) using my extension need to import them. Side Question 2: Can I just ignore this error? And tell the 3rd-party app developers they also can ignore it? After the user tapped on the ContainingApp icon in the sharing dialog, my Sharing Extension will show its dialog, presenting the shared item it got from the HostApp, and let the user edit the text. When the user taps the "Save"-button in my extension, it creates a ShareResult struct to send back to the HostApp, and dismisses the sheet. This (kinda) works when I share plain text with the 􀈂Text button in my HostApp. My ContainingApp icon is shown together with Mail, Messages, and other apps that can process plain text; with shortcuts to persons and devices (AirDrop targets) in the line above, and with actions (Copy, New Quick Note, Save to Files, Save to Citator, Certificat, Airdrop) below. When I choose my ContainingApp, the extension runs and shows the text it got. ("Kinda" because I am still struggling to send data back. See below...) So the principal operation works... Side Question 3: In the HostApp, can I use ShareLink() to present the Share-sheet and receive the result struct or do I always need to activityViewController!.completionWithItemsHandler = completionHandler windowScene.keyWindow?.rootViewController?.present(activityViewController!, animated: true, completion: nil) and process the result in the completionHandler? If returning (any) data from the extension is possible with ShareLink() also, then how? I didn't find any sample showing this... I implemented the ShareLink() anyway (and ignore the result part for the moment). When I try to share a ShareInput struct with the 􀈂ShareLink button, the same persons are sorted differently, there are less app icons (9 instead of 13), and less actions (only 3: New Quick Note, Save to Files, AirDrop): Note that while the preview correctly shows the preview text provided ("shareInput"), the preview image left of it is blank (instead of arrowshape.right.fill): let preview = SharePreview("shareInput", image: Image(systemName: "arrowshape.right.fill")) When I choose my ContainingApp, the extension runs ... On iOS17, I see that indeed my ShareInput data arrived in my extension: ❗️itemProvider=<NSItemProvider: 0x301b1c460> {types = ( "com.myapp.shareInput" )} Library: ShareExtension | Subsystem: com.myapp.containingdemo.ShareExtensionDemo | Category: ShareSheet However, on iOS 16 it doesn't work: Host[8615:634470] [Type Declaration Issues] Type "com.myapp.shareInput" was expected to be exported in the Info.plist of Host.app, but it was imported instead. Host[8615:634462] [ShareSheet] Couldn't load file URL for Collaboration Item Provider:<NSItemProvider: 0x280f49180> {types = ( "com.myapp.shareInput" )} : (null) That error is shown before I choose the ContainingApp to share with. When I do that, I get: ShareExtension[8774:636786] [ShareSheet] ❗️itemProvider=<NSItemProvider: 0x28243a300> {types = ( "dyn.age8u", "public.file-url" )} which clearly shows the ShareInput struct was not transferred to the extension. But since I don't know how to transfer the ShareResult back to the HostApp when using a ShareLink, I cannot continue this approach anyway. When I try to share a ShareInput struct with the 􀈂JSON button (using present(activityViewController)), I see (both on iOS 16 and iOS 17): My extension (rather, the ContainingApp's icon) is not shown as Sharing target (even though it still has TRUEPREDICATE), which means that my code didn't manage to pack the ShareInput struct for the activityViewController - and thus it doesn't know what to share. I did the same as with the plainText item before: let shareInput = ShareInput(inputStr: "ShareInput as JSON") let preview = SharePreview("shareInput", image: Image(systemName: "arrowshape.right.fill")) VStack(spacing: 25.0) { Text("HostApp!") ShareButton(title: "Text", shareItems: [ItemSource(dataToShare: "sharing some text")]) ShareButton(title: "JSON", shareItems: [ItemSource(dataToShare: shareInput)]) ShareLink("ShareLink", item: shareInput, preview: preview) } (I will continue in the next posting)
15
0
847
Aug ’24
Message Filter Extension won't use Basic Auth
I am trying to set up a message filter extension that will use shared web credentials for basic auth when calling to its ILMessageFilterExtensionNetworkURL. I have associated domains set up for both "messagefilter:" and "webcredentials:" and the message filter IS correctly calling the ILMessageFilterExtensionNetworkURL with each message - so that part is working. As detailed here, I have set up Shared Web Credentials and my view controller is using SecAddSharedWebCredential() to save the creds to the correct domain. Using Authorization services, the creds are auto-filled into my app's login screen. When I go under Settings > Passwords, I see the creds are saved and they are the correct creds to the corrent website that matches ILMessageFilterExtensionNetworkURL. Regardless of all of this, the deferQueryRequestToNetwork() refuses to use the creds and implement Basic Auth in its URL call. It makes the call to the correct URL, it just won't use the Shared Web Creds for basic auth. Any help would be greatly appreciated.
0
1
482
Jul ’24
Account Authentication Modification Extension on iOS 18
We currently have an Account Authentication Modification Extension in our iOS App so that users can update their passwords directly from within the Passwords section in the iOS Settings App. On iOS 18 beta3 the extension is not executed from the new Passwords app. Instead the URL associated with the credentials is opened when choosing to change a password. Will it still be possible to integrate with the new Passwords app or is this no longer supported? https://developer.apple.com/wwdc24/10125 only mentions https://example.com/.well-known/change-password Also, can we provide the information to the Passwords app that our service does not support verification codes? So that the "set up verification code" option is not displayed for our website in the Passwords app.
1
0
634
Jul ’24
Conntent Filter network extension is not working with Sequoia Intel macOS
Hi, I had a Content Filter network extension. It is successfully working until Sonoma. I try to install and activate same network extension on Sequoia beta Intel Mac. But even I haven't got any user consent to activate and allow it. I haven't found any entry in Network settings. Do we need to make any changes in Sequoia MacOs to make it work? Thank you.
3
0
657
Jul ’24
IOS BroadcastExtension
Hello, I'm new here, I was developing a screen recording extension for an IOS application, I used the RPSBroadcastSampleHandler livekit as a basis, in tests a few months ago it worked, but after the long wait for publishing authorization the extension stopped working, I noticed which is not just mine but screen sharing from Google Meet, Zoom Mettings and others also don't work, I tested it on iPhone 14 pro and iPhone 6s, nothing worked, the option to select the extension appears but when clicking "start sharing" nothing happens and after a few seconds the sharing button returns to "start sharing", the same behavior in all tested apps, does anyone know what happens? Did you change the way you record and no app has updated? Internal error in IOS? Nothing logs in terminal just doesn't work.
1
0
606
Jul ’24
I am unable to debug a Safari extension in Xcode 16 beta 1 on iOS 18 beta
The process to reproduce: Create a new extension with Xcode 16 beta. Run it on the simulator or any iOS device with iOS 18 beta installed. Open Safari on your Mac, then open Develop -> Device you use. Unable to access these menus for iOS 18: 1. Extension - Extension Background Content 2. Extension - Extension Pop-up Page - popup.html However, for iOS 17.4, I can see these options in Develop -> Device iOS(17.4). I have another extension on the App Store that is not working on the iOS 18 beta, but I am unable to debug it because of this issue.
1
0
619
Jul ’24
Unable to invoke the host App in ShareExtension
I developed a Share Extension for my App. Using the following code in the extension, I am unable to invoke the main App; however, I noticed that the Bing App can be invoked normally. Therefore, I have two questions; Is there a bug in the invocation code? I used the extensionContext?.open method to invoke, and the callback flag always returns false; the scheme can be invoked normally in Safari How does the Bing App do it? this my code: extensionContext?.open(URL(string: “myappscheme://”)!, completionHandler: { succ in // print(“open (succ)”) // }) Environment: Mac OS: 15.0 Beta (24A5279h) iPad OS : 18 Beta 1 "
4
0
556
Jul ’24
Does SystemMemoryReset related to my Application abnormal exit?
Hello, we are currently developing a VPN application. Recently, we have encountered several cases where the Network Extension process terminates unexpectedly. We cannot find any related crash logs on the device, but we can find system SystemMemoryReset logs. The timestamps in these logs closely match (with millisecond accuracy) the times when our VPN process terminated unexpectedly. We have a few questions: 1.How is the SystemMemoryReset event generated, and can this event be avoided? 2.When a SystemMemoryReset occurs, can it cause our VPN background process to be killed or the system to reboot? 3.If the background process can be killed, what conditions need to be met for this to happen, and what methods can we use to prevent the VPN background process from being killed? 4.Based on these logs, does our application have any related issues (the process name is CorplinkTunnel)? Do you have any suggestions for modifications? SystemMemoryReset-2024-06-25-232108.log SystemMemoryReset-2024-06-29-025353.log SystemMemoryReset-2024-07-01-024655.log
1
0
617
Jul ’24