Post not yet marked as solved
I'm trying to understand what exactly is made possible by Media Device Discovery Extensions, what responsibility the containing app has, and what exactly is made available to other apps or the system, if anything.
I haven't been able to find any meaningful high level documentation, and WWDC 2022 session 10096 only mentions these new extensions in passing. The most comprehensive body of information I found is the example project:
https://developer.apple.com/documentation/devicediscoveryextension/discovering_a_third-party_media-streaming_device?changes=latest_beta&language=objc
However, I don't think it's working the way it should out of the box:
I've got the Client target app built and running on an iPad Pro running iPadOS 16 Beta 2
I've got the MacServer target running on a Mac Mini with macOS 13 Ventura Beta 2
I've got the Server target running on an iPhone with iOS 15.5. (Non-beta)
If I tap the AirPlay icon on the Client's video player, I can see the two servers, but selecting one just causes a spinner to show up next to its name. This keeps going for a while, eventually the spinner goes away again, but the device selection tick stays next to 'iPad'. The text "Select route" also doesn't change, which I think it's supposed to, judging by the code.
I've tried a variety of combinations of settings on the servers - bluetooth only, bonjour only, different protocols, etc., but I'm always getting the same behaviour.
Has anyone had any success in getting the example to work, and how? Is there any high level documentation available that I've missed?
Can someone explain what exactly we can build with this in more detail than "implementations of custom A/V streaming protocols?" The WWDC session video talks about 3rd party SDKs, so do these extensions have to be embedded in every app that would be streaming the video, implying that it's not useful for mirroring?
Post not yet marked as solved
Hi there,
We're developing an extension that have the minimum target version 14.0 and it's embedded to an application that have the minimum target version of 11.0 and we want to know what will be the behavior when we have that mismatch of minimal versions between Extension and the app that the extension is embedded to. Our main questions are:
Taking in consideration that we are able to build/upload to the store the app with those different target mismatches (let me know if this not gonna happen please) we can think that:
It's a common thing to have different versions for each target
Customers with iOS version < 14.0 will not be able to use the benefits of the extension but nothing changes for them
Customers with iOS version > 14.0 will be able to use the feature introduced by the extension
Thanks in advance!
Post not yet marked as solved
I am trying to record and play audio from keyboard extension in Swift, but it throws an error on line recordingSession.setActive(true)
Error: failed to record The operation couldn’t be completed. (OSStatus error 561015905.)
I have already set the key RequestsOpenAccess to true in info.plist and granted full access to the keyboard extension.
Post not yet marked as solved
I'm trying to use Network Extension to develop a VPN tool for iOS devices. I used a NETunnelProviderManager to create VPN configuration and created extension target conaining a subclass of NEPacketTunnelProvider.
But when I use NETunnelProviderManager.connection.startVPNTunnel() to enable the extension, I got a error output: "Failed to fetch info with type 2: Connection interrupted".
I checked my entitlements for both app and extension and they both contains PacketTunnel capability. And the info.plist for extension is correct with a principal class $(PRODUCT_MODULE_NAME).PacketTunnelProvider (which is identical to my provider class).
I want to know which configuration could cause the problem and how can I fix it. Thank for any helping.
Post not yet marked as solved
I'm developing iOS message extension to filter the unwanted message. The plugin needs a help from server to filter the message. However, the iOS returned the error NSURLErrorDomain while requesting the server.
Based on the official document, I defined the key/value pair in Info.plist of Message Extension.
ILMessageFilterExtensionNetworkURL has value: https://mydomain.io/api/v1/sms
The code that I test the request as follows:
let url = URL(string: "https://mydomain.io/api/v1/sms")!
var request = URLRequest(url: url)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("you-value-goes-here", forHTTPHeaderField: "X-API-KEY")
let task = URLSession.shared.dataTask(with: request) { data, _, error in
if let data = data {
print(data)
} else if let error = error {
print("Http failed: \(error)")
}
}
task.resume()
From the stack trace, as far as I known, there is a problem with dns resolution. Why does this happened and how to fix this case?
[0] (null) "_kCFStreamErrorCodeKey" : Int32(-72000)
[1] (null) "NSUnderlyingError" : domain: "kCFErrorDomainCFNetwork" - code: 18446744073709550613
[2] (null) "_NSURLErrorFailingURLSessionTaskErrorKey" : "LocalDataTask <B496A974-7009-4FCE-BF45-FEC07BA1E8DF>.<1>"
[3] (null) "_NSURLErrorRelatedURLSessionTaskErrorKey" : 1 element
[4] (null) "NSLocalizedDescription" : "A server with the specified hostname could not be found."
Thanks
Post not yet marked as solved
I want to set the push notification icon other than app icon like whatapp.
Post not yet marked as solved
I want to localize two value in info.plist.
First one is [ NSFileProviderDecorations - Item0 - Label ],
and second one is [ NSExtensionFileProviderActionName ].
I could localize first one using InfoPlist.strings. (and Label-NSStringFormat)
But it does not work for second one.
I tried InfoPlist.strings, Localizable.strings, ..., but i can't localize this key.
What should i do?
Post not yet marked as solved
I am sharing my CoreData model between my iOS main app target and a new Share Extension target like this post:
This is working well for the most part except for one thing. NSFetchedResultsController is not returning results when called from the Shared Extension. What is strange though is that if I do a plain NSFetchRequest in my Share Extension, I do get CoreData results returned that were originally saved from the main app...so I think Container setup as well as model must be being shared correctly via AppContainer.
NSFetchedResultsControllerDelegate controllerDidChangeContent is never called.
Any ideas or suggestions?
import UIKit
import MobileCoreServices
class ShareViewController: UIViewController {
private(set) lazy var resultsController: NSFetchedResultsController<Person> = createFetchedResultsController()
override func viewDidLoad() {
super.viewDidLoad()
let fetchRequest = NSFetchRequest<Person>(entityName: "Person")
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "date", ascending: false)]
do {
/// this works!
let persons = try CoreDataManager.shared.managedObjectContext.fetch(fetchRequest)
print("Got \(persons.count) Persons")
} catch {
print("Fetch failed")
}
activateResultsController()
}
func createFetchedResultsController() -> NSFetchedResultsController<Person> {
CoreDataManager.shared.container.viewContext.stalenessInterval = 0
CoreDataManager.shared.container.viewContext.refreshAllObjects()
CoreDataManager.shared.container.viewContext.stalenessInterval = -1
let fetchRequest = NSFetchRequest<Person>(entityName: "Person")
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "date", ascending: false)]
////managedObjectContext: CoreDataManager.shared.managedObjectContext,
let controller = NSFetchedResultsController(
fetchRequest: fetchRequest,
managedObjectContext: CoreDataManager.shared.managedObjectContext,
sectionNameKeyPath: nil,
cacheName: nil
)
controller.delegate = self
return controller
}
private func activateResultsController() {
do {
try resultsController.performFetch()
} catch {
fatalError("Failed to fetch entities: \(error)")
}
}
}
// MARK: - Results Controller Delegate
extension ShareViewController: NSFetchedResultsControllerDelegate {
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
guard let sections = resultsController.sections else {
return
}
let section = sections[0]
let rows = section.numberOfObjects
print("rows=\(rows)")
}
}
import UIKit
import CoreData
class CoreDataManager {
static let shared = CoreDataManager()
internal var container: NSPersistentContainer
var managedObjectContext: NSManagedObjectContext {
container.viewContext
}
init() {
container = NSPersistentContainer(name: Constants.name)
guard let storeDirectory = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first else {
// We'll throw a fatalError() because we can't really proceed without storeDirectory
fatalError(file: "Could not find .applicationSupportDirectory - exiting")
}
let storeURL = storeURL(for: "group.mygroup.testshareextensioncoredata", databaseName: "\(Constants.name)")
let storeDescription = NSPersistentStoreDescription(url: storeURL)
container.persistentStoreDescriptions = [storeDescription]
container.loadPersistentStores(completionHandler: { storeDescription, error in
if let error = error as NSError? {
// We'll throw a fatalError() because we can't really proceed without loading the PersistentStore
fatalError("loadPersistentStore failed \(error), \(error.userInfo)")
}
})
}
// MARK: - Core Data Saving support
func saveContext() {
managedObjectContext.performAndWait {
if managedObjectContext.hasChanges {
do {
try managedObjectContext.save()
} catch {
}
}
}
}
/// Returns a URL for the given app group and database pointing to the sqlite database.
func storeURL(for appGroup: String, databaseName: String) -> URL {
guard let fileContainer = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroup) else {
fatalError("Shared file container could not be created.")
}
return fileContainer.appendingPathComponent("\(databaseName).sqlite")
}
}
internal extension CoreDataManager {
enum Constants {
static let name = "ShareExtensionCoreDataTest"
}
}
Post not yet marked as solved
Please can anyone teach me and guide me through for how to download the driver for asix ethernet adapter on mac os Monterey and please do send the link to me to download it Thank you!
Post not yet marked as solved
In MacOS I can achieve this via
func sendKeyStrike(_ keyCode: CGKeyCode, useCommandFlag: Bool) {
let sourceRef = CGEventSource(stateID: .combinedSessionState)
if sourceRef == nil {
NSLog("FakeKey: No event source")
return
}
let keyDownEvent = CGEvent(keyboardEventSource: sourceRef,
virtualKey: keyCode,
keyDown: true)
if useCommandFlag {
keyDownEvent?.flags = .maskCommand
}
let keyUpEvent = CGEvent(keyboardEventSource: sourceRef,
virtualKey: keyCode,
keyDown: false)
keyDownEvent?.post(tap: .cghidEventTap)
keyUpEvent?.post(tap: .cghidEventTap)
}
Is there a function call either in XCUITest or any other framework to achieve keyboard strokes in IOS?
IOS Seems to have HID keycodes but I just can't find a way to send them to the device. Either through XCUITest or any other framework. (I am ok with simulating a HID device using python or something else to command my iOS device as well.
Post not yet marked as solved
I've configured an item and placeholder in NSFileProviderExtension iOS extension, and an XPC service in the provider (based on the template for XPC service for Mac, but as part of the NSFileProviderExtension
When connecting to the service from the app using code example in getFileProviderServicesForItem I am getting an error straight in the completion handler of that function:
Error Domain=NSCocoaErrorDomain Code=4097 "Error while sending identifierForItemAtURL:completionHandler:" UserInfo={NSDebugDescription=Error while sending identifierForItemAtURL:completionHandler:, NSUnderlyingError=0x2833640c0 {Error Domain=NSCocoaErrorDomain Code=4097 "connection from pid 30324 on anonymousListener or serviceListener" UserInfo={NSDebugDescription=connection from pid 30324 on anonymousListener or serviceListener}}}
Could you maybe suggest what I am missing? Or, is there an example somewhere of the FileProvider extension with the service being called from the app?
Code:
File Provider service definition: https://github.com/simplex-chat/simplex-chat/blob/af3dcc4a9a9b24751bf9d74af67cf8e7d119597a/apps/ios/SimpleX%20Service/SimpleXFPService.swift
Application code that calls the service: https://github.com/simplex-chat/simplex-chat/blob/af3dcc4a9a9b24751bf9d74af67cf8e7d119597a/apps/ios/Shared/FPService.swift
Thank you!
Post not yet marked as solved
I'm trying to convert an existing Chrome Extension to Safari Web Extension.
Immediately after convert, xcode opens and I build the project. Everything looks perfect in Safari: the popup works fine, the context menu item is there, options are there.
The moment I restart Safari, the context menu item disappears and service worker is not loaded.
My Manifest v3:
"background": {
"service_worker": "js/background.js"
},
"permissions": [
"contextMenus",
"activeTab",
"storage"
],
My background script:
chrome.contextMenus.removeAll(() => {
chrome.contextMenus.create(properties);
});
Post not yet marked as solved
Hello, everyone!
Help me please to find answer. I have two applications: App-1 with share extension and App-2 without it. From the second app I can open share extension via UIActivityViewController. But I need this extension in the second application to open immediately by pressing a button, and not through UIActivityViewController. Can I do this?
Post not yet marked as solved
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.
Post not yet marked as solved
I know AppleJavaExtensions-1.4.jar is Apple License.
https://developer.apple.com/library/archive/samplecode/AppleJavaExtensions/Listings/README_txt.html
I wonder that AppleJavaExtensions-1.4.jar is free or not when it is included in commercial SW?
"In consideration of your agreement to abide by the following terms, and subject to these terms, Apple grants you a personal, non-exclusive license, under Apple's copyrights in this original Apple software (the "Apple Software")"
In this sentence, I want to konw the meaning of "personal". Does it mean that it cannot be used for company?
Please let me know as possible. Thank you.
Post not yet marked as solved
I'm trying to create a "hello world" a Message Filtering extension for iOS based on the following steps:
Create a new project.
Go to File -> Target -> Add Message Filter App Extension, enter a name MyMessageFiltering. Xcode generate the folder MyMessageFiltering contains MessageFilterExtension.swift
In the MessageFilterExtension.swift, add one line below the handle function as follow:
func handle(_ queryRequest: ILMessageFilterQueryRequest, context: ILMessageFilterExtensionContext, completion: @escaping (ILMessageFilterQueryResponse) -> Void) {
NSLog("FILTEREXTENSION - handle") // add the log to see check the function handle
Run the app
Enable the app in message extension on iPhone by Settings -> Message -> Unknown & spam
Start the console app and record the phone.
Send a sms message to iPhone by an unknown number (which is not existing in iPhone contact).
There is no log from the console app or XCode console
What steps did I do wrong to test the sms extension filtering ?
Post not yet marked as solved
Safari Version 14.0.1 (16610.2.11.51.8)
I am porting a Chrome/Firefox/Edge extension to Safari Web Extension. Mostly, the process was painless, I am, however, seeing quite different behavior in the tab ids generated by Safari compared to Chrome, Firefox, and Edge. My extension has callbacks for each of these browser.webNavigation events:
browser.webNavigation.onBeforeNavigate
browser.webNavigation.onCommitted
browser.webNavigation.onDOMContentLoaded
In each of these I rely on the tab id for various future tab targeting operations. When opening a new tab, the details object passed to each of these callbacks has a non-zero tabId on Chrome, Firefox, and Edge. However, in Safari, the tabId is always zero. To debug, I added one more callback:
browser.webNavigation.onCompleted
At this point Safari finally has a non-zero tabId in the details param. Needless to say this is causing some consternation with achieving the same outcomes as tab tracking on Chrome, Firefox, and Edge. It's like Safari is treating new tabs as "non tabs" until navigation completes. You can even see it when trying to get the tab by tabId=0:
browser.tabs.get(tabId) // tabId=0 here
	.then(tab => {
		// tab is undefined
	});
Seems like this might be a bug. I can't imagine why the behavior is so different from other browsers. Any ideas on how to work around?
Post not yet marked as solved
Hi,
Before iOS 15.4, getStateOfContentBlocker would return the correct content blocker state when moving the app to background, going to Safari settings to enable/disable it, and then back to the app.
Now, on iOS 15.4, the state returned by the method is not updated unless I kill the app and start it again.
I confirmed that the same code on iOS 15.2 works as expected.
Running on Xcode 13.3.
Has anyone else experienced this?
Thanks.
Post not yet marked as solved
Hello I am facing issue while implementing
browser.tabs.onUpdated.addListener(function (tabID, changeInfo, tab)....
This is only working while page is getting reloaded but if only URL is updated without reloading the page this event is not firing.
The same thing is working fine in firefox and chrome.
Do I need to add something extra?
Post not yet marked as solved
Hi,
I am building a Safari Web Extension and I am seeing this warning in my console:
[NSExtension] Extension request contains input items but the extension point does not specify a set of allowed payload classes. The extension point’s NSExtensionContext subclass must implement +_allowedItemPayloadClasses. This must return the set of allowed NSExtensionItem payload classes. In future, this request will fail with an error. Extension: <EXConcreteExtension: 0x7f9ca5abe440
I am not sure how to go about this. I have not found any documentation regarding usage of allowedItemPayloadClasses has anyone seen this before?