I'm using the next code to know when a device is plugged in:
- (void)applicationDidBecomeActive:(UIApplication *)application
{
//code...
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(accesoryChanged:) name:EAAccessoryDidConnectNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(accesoryChanged:) name:EAAccessoryDidDisconnectNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(accesoryChanged:) name:UIScreenDidConnectNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(accesoryChanged:) name:UIScreenDidDisconnectNotification object:nil];
EAAccessoryManager *accessoryManager = [EAAccessoryManager sharedAccessoryManager];
[accessoryManager registerForLocalNotifications];
}
- (void)accesoryChanged:(NSNotification*)note;
{
if(note.name == EAAccessoryDidConnectNotification)
{
EAAccessory* accessory = [note.userInfo objectForKey:EAAccessoryKey];
//code...
}
else if(note.name == EAAccessoryDidDisconnectNotification)
{
EAAccessory* accessory = [note.userInfo objectForKey:EAAccessoryKey];
//code...
}
}
And with:
accessory.name
I can get the device's name, but I couldn't find a way to know what kind of device is (i.e: a controller or a HDMI adapter).
Is there any way to get this information?
Thanks in advance.
The EAAccessory object has properties for the manufacturer, modelNumber, and serialNumber. You can also look at the array of protocolStrings to get an idea of the device's capabilities.
When deciding whether to connect to an accessory, you should use the accessory’s declared protocols to make your determination. The protocols associated with an accessory indicate the types of data the accessory is capable of processing. You may use other properties to help you decide whether or not to connect to an accessory but the list of protocols should be the key factor you consider.
Related
I want to detect UIDeviceOrientationFaceDown. How can i do this???
Actually i want to perform some action when my iphone face is down on flat surface.
how is it possible??? plz help me to do this.
i have this code, but don't know where and how apply this code
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
BOOL getOrientationUpdates = [[UIDevice currentDevice] isGeneratingDeviceOrientationNotifications];
NSLog(#"will receive orientation notifications: %#", getOrientationUpdates?#"YES":#"NO");
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
if there is any tutorial then please suggest me that
Thanks in Advance and most welcome to your precious help and suggestions.
You can accomplish this by detecting the ProximityState of iPhone. Using the [UIDevice currentDevice] singleton, setting the proximityMonitoringEnabled to YES. you can access the proximity information through the proximityState property.
[[UIDevice currentDevice]proximityState];
iPhone has a sensor turns off the screen when you put it on your ear during a call, AFAIK that is an infrared sensor. and you can access it.
EDIT:
You can also accomplish it using the below code. UIDeviceOrientationFaceDown
The device is held parallel to the ground with the screen facing downwards. (regardless if it touched any object) if you want to know if the iPhone touched an object, detect the proximity state of device.
[[NSNotificationCenter defaultCenter] removeObserver:self];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(detectOrientation) name:#"UIDeviceOrientationDidChangeNotification" object:nil];
-(void)detectOrientation;{
switch ([[UIDevice currentDevice] orientation]) {
case UIDeviceOrientationPortrait:
{
NSLog(#"portrait");
}
break;
case UIDeviceOrientationPortraitUpsideDown:
{
NSLog(#"portraitUpSideDown");
}
break;
case UIDeviceOrientationLandscapeLeft:
{
NSLog(#"landscapeLeft");
}
break;
case UIDeviceOrientationLandscapeRight:
{
NSLog(#"landscapeRight");
}
break;
case UIDeviceOrientationFaceDown:
{
NSLog(#"facedown!!");
}
break;
default:
break;
}
}
}
EDIT: to answer the question in comment. add this line in your viewDidLoad
[UIDevice currentDevice].proximityMonitoringEnabled = YES;
[[NSNotificationCenter defaultCenter] removeObserver:self];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(handleProximityChangeNotification:) name:UIDeviceProximityStateDidChangeNotification object:nil];
then write a method
-(void)handleProximityChangeNotification{
if([[UIDevice currentDevice]proximityState]){
NSLog(#"...");
}
}
You can use the z value from accelerometer sensor (-1 <= z <= 1). If your device is facing down, the z value will be in 0 < z <=1 (0 when it's facing parallel to the ground, 1 when it's facing perpendicular to the ground). To get this data you can use CMMotionManager
#import <CoreMotion/CoreMotion.h>
CMMotionManager *cm=[[CMMotionManager alloc] init];
cm.deviceMotionUpdateInterval=0.2f;
[cm startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue]
withHandler:^(CMDeviceMotion *data, NSError *error) {
if(data.gravity.z>=0.3f)//
{
//DO something
}
}];
Don't forget to add CoreMotion framework to your project.
I need to know when a sharer has been authorized (to change some UI) and it looks like there's a SharerDelegate sharerAuthDidFinish method which (I think) I implemented, but it doesn't get called.
Anyone?
Thanks!
In SHKSharer.m, there is the following code:
- (void)authDidFinish:(BOOL)success
{
[[NSNotificationCenter defaultCenter] postNotificationName:#"SHKAuthDidFinish" object:self userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:success] forKey:#"success"]];
if ([self.shareDelegate respondsToSelector:#selector(sharerAuthDidFinish:success:)]) {
[self.shareDelegate sharerAuthDidFinish:self success:success];
}
}
So you can listen for the notification in whatever class needs to know like such:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(sharerAuthorized:) name:#"SHKAuthDidFinish" object:nil];
and then implement a method like:
- (void)sharerAuthorized:(NSNotification *)notification {
//check for success and type of sharer
//do whatever you need to do once it is authorized
}
I'm not sure the exact reason for it (other than the ambiguity described below), but I've read that multiple observers shouldn't be added to the NSNotificationCenter for the same object. However, I would like to add a second selector/name pair to the same object in the notification center.
I added the first one as follows:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(method1:)
name:#"method1Notification"
object:nil];
Option 1:
To add the second (like below) would seem to add "self" to the notification center again.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(method2:)
name:#"method2Notification"
object:nil];
Is this okay? Or, if necessary, is there a way to simply add another selector/name pair to the "self" entry in the default notification center?
Option 2: (Pseudocode)
[[[NSNotificationCenter defaultCenter] mySelfObserver]
addSelector:#selector(method2:)
name:#"method2Notification"
object:nil];
Ambiguity:
It would seem that either way, if it were added a second time, in dealloc: it might need to be removed as an observer twice?
[[NSNotificationCenter defaultCenter] removeObserver:self];
// ... REMOVE IT AGAIN IF OBSERVER ADDED TWICE TO NOTIFICATION CENTER?
Everything you posted ("Option 1") is okay. See the docs:
removeObserver:
Removes all the entries specifying a given observer from the receiver’s dispatch table.
- (void)removeObserver:(id)notificationObserver
You just need to call removeObserver: once; there's a separate removeObserver:name:object: method if you want to remove just a single observance of a specific notification.
I think you're a little confused. It's perfectly fine to add a given observer any number of times, as long as the notifications or objects are different.
If you add an observer multiple times for a single notification/object combo, you will receive multiple notifications -- your notification method will be called once for each time you added the observer. This is usually not desirable, and I think that's the recommendation that you've seen.
You also only need to call removeObserver: once for any observer, no matter how many things it's observing.
- (void)registerForNotifications
{
NSNotificationCenter * noteCenter = [NSNotificationCenter defaultCenter];
[noteCenter addObserver:self
selector:#selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification
object:nil];
[noteCenter addObserver:self
selector:#selector(keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification
object:nil];
// Totally fine up to this point; this object is observing two different
// notifications.
// Now, add two different observations for the same notification, but
// with _different_ objects:
[noteCenter addObserver:self
selector:#selector(fluffyHasReproduced:)
name:RabbitsHaveReproducedNotification
object:MyRabbitFluffy];
[noteCenter addObserver:self
selector:#selector(luckyHasReproduced:)
name:RabbitsHaveReproducedNotification
object:MyRabbitLucky];
// This is fine; the appropriate rabbit notification method will only be
// called when the corresponding rabbit reproduces.
// However...
// This will make luckyHasReproduced: be called _twice_ whenever
// MyRabbitLucky posts RabbitsHaveReproducedNotification
[noteCenter addObserver:self
selector:#selector(luckyHasReproduced:)
name:RabbitsHaveReproducedNotification
object:MyRabbitLucky];
// Further,
// this is probably not what you want. otherRabbitsHaveReproduced: is
// going to be called whenever either Fluffy or Lucky post their
// notifications, too. The nil object acts as a wildcard.
[noteCenter addObserver:self
selector:#selector(otherRabbitsHaveReproduced:)
name:RabbitsHaveReproducedNotification
object:nil];
}
Later, when appropriate (viewWillDisappear:, or viewDidUnload: for view controllers, depending on the nature of the notifications; dealloc for other objects):
- (void) unregisterForNotifications {
// Clear out _all_ observations that this object was making
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
So I have this function inside NotificationManager class.
-(void) postNotificationForClassName:(NSString*)className withObjects:(NSArray*)objects withError:(BOOL)withError
{
notificationName = [NSString stringWithFormat:#"didLoad%#",className];
[[NSNotificationCenter defaultCenter]
postNotificationName:notificationName object:self];
}
now, let's say I have 2 classes , A and B.
from A's method foo() I do the following:
[[NotificationManager sharedManager]
postNotificationForClassName:#"A" withObjects:objects withError:NO]
from B's method goo() I do the following:
[[NotificationManager sharedManager]
postNotificationForClassName:#"A" withObjects:objects withError:NO]
Now, I'm curious what should I do in case I want to listen only to notifications being posted from Class A.
Is this suppose to work ?
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(didLoadData:)
name:#"didLoadA" object:classAObject];
Cause I'm assuming that when I'm calling
[[NSNotificationCenter defaultCenter]
postNotificationName:notificationName object:self];
and I pass the "self", then the "self" will be the NotificationManager and not the class A or B that called the NotificationManager method.
Am I right or wrong here ? and if I'm right, is there a way to do what I want to accomplish?
Thanks!
self is a special variable, always referring to the object that received the message currently being handled. In NotificationManager's -postNotificationForClassName:withObjects:objectswithError:withError:, self is a NotificationManager (or descendent). As for self in the call to -addObserver:..., it depends on what method the call occurs in.
As you've noticed, -addObserver:... lets you monitor notifications from specific objects. You could use this to monitor messages from As if you use the class A as the object:
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(didLoadData:)
name:#"didLoadA" object:[A class]];
However, you'll also need to change the notification sender in -postNotificationForClassName:withObjects:objectswithError:withError:.
-(void)postNotificationForClassName:(NSString*)className
withObjects:(NSArray*)objects
withError:(BOOL)withError
from:(id)sender
{
notificationName = [NSString stringWithFormat:#"didLoad%#",className];
[[NSNotificationCenter defaultCenter]
postNotificationName:notificationName object:[sender class]];
}
I get twice notification on keyboard down and once on keyboard up…
In my class I put notifications for keyboard:
-(id)init… {
…
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
…
}
to do frame adjustment on keyboard slide.
Later during the class work I use 'ABPeoplePickerNavigationController' to select address.
…
ABPeoplePickerNavigationController *userPicker=[[ABPeoplePickerNavigationController alloc] init];
…
[viewController presentModalViewController:userPicker animated:YES];
…
I’ve found that on ‘presentModalViewController’ I get twice ‘UIKeyboardWillHideNotification’ , BUT once ‘UIKeyboardWillShowNotification’ – when the picker goes out.
Pretty strange.
I tried to remove observer for ‘UIKeyboardWillHideNotification’ from the class initialization (to find any double observer declarations). However, after this remove no ‘UIKeyboardWillHideNotification’ notifications at all.
Why I get different amount of notifications on keyboard up and down?
May be I do something wrong?
Thanks.
It is quite common (especially with the *WillDoSomething message) to receive a notification twice though you expected just once.
What you could do to fix the problem is to have a boolean somewhere which stores the state of the UI. For instance, if keyboardUp is false would mean that you already move the UI to the default state.