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?
Related
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.
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 able to enable Bluetooth with help of the Private Framework.
Now I have to search for nearby devices.
I guess the deviceScanningEnabled command is the right one, but how do I get the returned Devices? Is there any callback-Function? I read about some Notifications which will be in the NotificationCenter?!
How do I use it in this context?
As far as I know, the bluetooth manager gets the list after OS has filtered the results - meaning you will only get the nearby headset devices and not all generic devices. If you need to find all generic devices you will have to use #rajagp's answer.
In the case that finding headsets are enough, then you can use notifications as you said; the notification for discovering a device is called "BluetoothDeviceDiscoveredNotification". You first need to list the notifications with:
[[NSNotificationCenter defaultCenter]
addObserver: self
selector: #selector( your_discovery_method_name)
name: #"BluetoothDeviceDiscoveredNotification"
object: nil];
the "your_discovery_method_name" is the method you write that shows/accepts the notification. It will look something like this:
-(void) your_discovery_method_name:(NSNotification *) notification {
self.device = [notification object];
NSLog(#"found: %#",self.device.address);
// ...
}
The device is from type BluetoothDevice.
If you are developing for a jailbroken phone , I'd recommend the third party BlueTooth library - BTStack. Its easy to use and has been working quite well for me. Its available at : http://code.google.com/p/btstack/.
replace
[btManager setDeviceScanningEnabled:YES];
with
[btManager scanForServices:0xFFFFFFFF];
i don't know why, but you'll discover all the devices nearby. Then you can pair the device.
This is where i got stuck... i am not able to get connections or exchange data