I am building sdk which at point of time requires to communicate with third party app and communication broadly means here notifiying some event may or may not with any data.
I used NotificationCenter to do this but now I found somewhere written that it is for intra-app communication. And thats the behaviour I found when I run my code.
NotificationCenter.default.post(name: action, object: nil, userInfo: jsonObject)
this is the listener I added in sdk
NotificationCenter.default.addObserver(self, selector: #selector(onReceive(_:)), name: Notification.Name.ACTION_PAYMENT_ACK, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(onReceive(_:)), name: Notification.Name.ACTION_PAYMENT_CMP, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(onReceive(_:)), name: Notification.Name.ACTION_PAYMENT_REJ, object: nil)
I also found something written related to darwin notification but that was too old a post. How can I do inter-app communication.
I am looking for something like Broadcast in android.
Inter app communication is described here.
Since you want to do it without manual intervention, only the 2nd part, Using URL Schemes to Communicate with Apps, is relevant for you. It says
A URL scheme lets you communicate with other apps through a protocol
that you define. To communicate with an app that implements such a
scheme, you must create an appropriately formatted URL and ask the
system to open it. To implement support for a custom scheme, you must
declare support for the scheme and handle incoming URLs that use the
scheme.
Related
I use deep-linking to let my users navigate to my app's page in the iOS Settings app, where I allow the user to set how many Core Data backups they want to store.
Settings is kind enough to provide a link back to the app, which is awesome, but I'd like to know when the user comes back specifically from Settings so that I can then prune the Core Data backups.
Is there a notification I can observe, or some other way I can tell when the app comes to the foreground specifically after leaving Settings?
I'm programming in Swift 4.2. Thanks!
As suggested by #mschmidt, the answer was simple; I just needed to register an observer for UserDefaults.didChangeNotification. Something like the following:
NotificationCenter.default.addObserver(
self,
selector: #selector(userDefaultsDidChange),
name: UserDefaults.didChangeNotification,
object: nil
)
#objc private func userDefaultsDidChange() {
coreData.pruneBackups()
}
I have an HQ Answer bot that is in the form of an iOS app. Basically, I have the entire bot completed and it runs once the HQ Trivia websocket opens, however I am having issues with the last step, which is to send the best answer from the bot to the user in the form of a push notification, since they will be using the HQ app when the game is live and the bot is running. In my viewDidLoad I have the following code:
override func viewDidLoad() {
super.viewDidLoad()
getSocketURL()
let notificationCenter = NotificationCenter.default
notificationCenter.addObserver(self, selector: #selector(appMovedToBackground), name: Notification.Name.UIApplicationWillResignActive, object: nil)
}
getSocketURL() checks to see if the game is live and if so it runs the bot, however I want this to operate when the user has the app killed or it is in the background.
Finally here is where the notification should be sent locally when the bot finds the correct answer:
private func getMatches()
{
let options = [answer1, answer2, answer3]
AnswerController.answer(for: question, answers: options) { answer in
print("Predicted correct answer: \(answer.correctAnswer)")
print("-----")
self.bestAnswer = answer.correctAnswer
self.sendNotification(question: self.question, answer: "Best Answer: \(self.bestAnswer)") // Send the user a notification
self.updateLabels()
}
}
To sum up, I am looking for a way that will let the bot run whenever the game is live without the user having the app open and in the foreground, since they will be in the HQ app. Is there any way to do this with local notifications and if no what steps would I have to take to do something like this using something like Firebase, that is if I still want the bot to run locally on the user's phone.
Is there any way to call container app method from extension keyboard?
I tried by using following NSNotificationCenter, But still its not working.
I have added NSNotificationCenter and method into my main container app.
NSNotificationCenter.defaultCenter().addObserver(
self,
selector: #selector(method),
name: "methodClicked",
object: nil)
func method(){
//doing stuff
}
and in my app extension keyboard I'm checking if container app is currently visible then post that notification NSNotificationCenter.defaultCenter().postNotificationName("methodClicked", object: nil)
Please post answer in Objective-c or Swift if anyone know proper way to do it. Thanks in advance.
I tried to do the same thing and realized (for now) that the only way to make an extension call a function on it's containing app is via remote server.
that means when an event on the extension occur you can make a call to your remote server that will notify your app (using notification).
Probably an overkill but it should work.
I'm trying to learn about CoreBluetooth and External Accessories on iOS.
First, I tried to see a list of devices connect to my phone via Bluetooth via print(EAAccessoryManager.sharedAccessoryManager().connectedAccessories) ... despite having 3 devices connected (according to the Settings app), I'm given an empty array.
Next, I tried registering for connect / disconnect notifications:
import UIKit
import ExternalAccessory
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self,
selector: "somethingConnected:",
name: EAAccessoryDidConnectNotification,
object: nil)
NSNotificationCenter.defaultCenter().addObserver(self,
selector: "somethingDisconnected:",
name: EAAccessoryDidDisconnectNotification,
object: nil)
EAAccessoryManager.sharedAccessoryManager().registerForLocalNotifications()
}
func somethingConnected(name: EAAccessory) {
print("here")
}
func somethingDisconnected(name: EAAccessory) {
print("there")
}
}
... I receive nothing when I turn off/on (and thus disconnect/connect) a simple Bluetooth speaker I have.
I am seeing this issue (notifications not delivering until after the completion block of showBluetoothAccessoryPickerWithNameFilter() executes), but, generally, it seems like either:
A) Something with iOS isn't working correctly
B) I'm doing something wrong (the more likely of the two).
Do I need to have a special MFI certificate installed to see a list of connected Accessories? Why aren't notifications delivering?
Any recommendations / code examples are greatly appreciated.
Update
Most importantly: Still don't know why connectedAccessories doesn't work, so advice on this piece is greatly desired.
That said, re-reading the Apple Developer documentation, I don't believe that it's correct / possible to use NSNotificationCenter.defaultCenter().addObserver with these types of notifications.
Specifically, the documentation states that EA notifications will not be delivered until showBluetoothAccessoryPickerWithNameFilter() is called -- e.g. the EAAccessoryDidConnectNotification and EAAccessoryDidDisconnectNotification are meant to inform the app about what the User did with the picker dialogue. It doesn't seem that they are system-level notifications that can be picked up by NSNotificationCenter.
Please correct me if this is an incorrect reading.
you should change
selector: "somethingConnected:"
into
selector: #selector(somethingConnected:)
,than it will fire.
For more details, please see the following website:
Why does EAAccessoryDidConnectNotification occur twice?
TLDR: Is it possible to send realtime messages or notifications between iOS App and it's Extension?
I'm writing an iOS App with an extension that are part of the same App Group and share the same CoreData (SQLite database). I can read and write to the database using CoreData from the App and from the extension, they both share the same content.
My Question is: Is it possible to send messages or notifications between the App and the extension to notify the other to update if necessary?
I tried sending notifications through NSNotificationCenter but that does not go "out" of the App/Extension, same issue if I try to write to the group shared NSUserDefaults and listen to NSUserDefaultsDidChangeNotification. This works inside the App but the extension does not receive anything (when I know that it is launched and it share the same NSUserDefaults). Any idea how to keep things in sync?
TLDR: No, but there's a hack
There's no true interprocess communication for iOS apps, with or without extensions. NSDistributedNotification still hasn't made the trip from OS X to iOS, and probably won't.
With some extension types you can open URLs via NSExtensionContext and use them to pass data to an app that handles the URL. This brings the app to the foreground, which doesn't sound like what you want.
There is a hack that might get you what you need, though.
Instead of writing to user defaults, write to a file in your app group directory.
Don't just write the file directly-- use NSFileCoordinator to do coordinated writes to the file.
Implement NSFilePresenter on an object that wants to know about changes to the file, and make sure to call [NSFileCoordinator addFilePresenter:someObject]
Implement the optional presentedItemDidChange method on your file presenter.
If you do all of this right, you can write to this file from either the app or the extension, and then have presentedItemDidChange be automatically called in the other one. As a bonus you can of course read the contents of that file, so you can pass arbitrary data back and forth.
There is a hack that you can use to communicate between any two apps in iOS or app and extension. The only thing - it doesn't work with NetworkExtension since Apple is blocking any I/O in it.
You can post notification to the DarwinNotificationCenter this way:
let notificationName = CFNotificationName("com.notification.name" as CFString)
let notificationCenter = CFNotificationCenterGetDarwinNotifyCenter()
CFNotificationCenterPostNotification(notificationCenter, notificationName, nil, nil, false)
In your app add observer:
let notificationName = "com.notification.name" as CFString
let notificationCenter = CFNotificationCenterGetDarwinNotifyCenter()
CFNotificationCenterAddObserver(notificationCenter,
nil,
{ (
center: CFNotificationCenter?,
observer: UnsafeMutableRawPointer?,
name: CFNotificationName?,
object: UnsafeRawPointer?,
userInfo: CFDictionary?
) in
print("Notification name: \(name)")
},
notificationName,
nil,
CFNotificationSuspensionBehavior.deliverImmediately)
Some links:
https://github.com/choefele/CCHDarwinNotificationCenter
https://developer.apple.com/documentation/corefoundation/1542572-cfnotificationcentergetdarwinnot
https://developer.apple.com/library/content/documentation/Darwin/Conceptual/MacOSXNotifcationOv/DarwinNotificationConcepts/DarwinNotificationConcepts.html
For an alternative means of doing general-purpose bidirectional communication between host app and app extension, try MMWormhole:
http://www.mutualmobile.com/posts/mmwormhole
https://github.com/mutualmobile/MMWormhole
It’s a fairly lightweight wrapper around CFNotificationCenter, and uses “Darwin” notifications to do interprocess communication (IPC).
It passes payloads back & forth using the apps’ shared container, and encapsulates even having to create the file(s) themselves.
The class (and the sample app in the repo) seem to work well, and are quite responsive.
I hope this also helps.
I've been struggling with the same issue and haven't found a clean solution either. Another hacky way to solve this is to simply run a timer in the extension and check the values in the shared container preferences/database periodically and then update if required. Not elegant, but it seems to work.