I try to send local notification. Here some code for class sending the notification:
#interface Sender : UIView
{
NSInteger itemID;
}
#implementation Sender
-(void) changedProperty
{
[[NSNotificationCenter defaultCenter] postNotificationName:#"NotificationName" object:NULL];
}
And here the code to receive this notification:
#interface Listener : UIViewController
{
}
#implementation Listener
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(selectedItem:) name:#"NotificationName" object:NULL];
}
- (void)viewDidUnload
{
[super viewDidUnload];
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"NotificationName" object:NULL];
}
-(void) selectedItem:(NSNotification *) notification
{
// some actions
}
But this code doesn't work. Debugging I see how postNotificationName: object works but the method selectedItem: doesn't call
UPDATE.
Here is more code. Maybe this will help.
extern const NSString* selectItemNotificationName;
#interface vRoomSelectorItem : UIView
{
RoomSelectorItemBackground backgroundType;
NSInteger itemID;
}
#property NSInteger itemID;
-(void) setBackgroundType:(RoomSelectorItemBackground) backgroundType;
#interface vRoomSelectorItem ()
#property RoomSelectorItemBackground backgroundType;
#end
#implementation vRoomSelectorItem
const NSString* selectItemNotificationName = #"Reservation.SelectRoom";
-(RoomSelectorItemBackground) backgroundType
{
return backgroundType;
}
-(void) setBackgroundType:(RoomSelectorItemBackground)value
{
if(backgroundType != value)
{
backgroundType = value;
[self changedBackgroundType];
}
}
-(void) changedBackgroundType
{
if(backgroundType == RoomSelectorItemFilled)
{
// animation
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:(NSString*)selectItemNotificationName object:NULL userInfo:[[NSDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithInteger:itemID], #"ID", NULL]];
});
}
else
// reverse animation
}
#import "vRoomSelectorItem.h"
#interface vcReservationSelectRoom : UIViewController
{
NSMutableArray* arraySelectorItems;
}
#implementation vcReservationSelectRoom
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(selectedItem:) name:(NSString*)selectItemNotificationName object:NULL];
for(NSInteger i = 1; i <= SELECTOR_ITEM_COUNT; ++i)
{
vRoomSelectorItem* newItem = [[vRoomSelectorItem alloc] initWithFrame:CGRectMake(/*coordinates*/)];
[self.view addSubview:newItem];
[newItem setBackgroundType:RoomSelectorItemTransparent];
[newItem setItemID:i];
[arraySelectorItems addObject:newItem];
newItem = NULL;
}
}
-(void) selectedItem:(NSNotification *) notification
{
// some actions
}
-(void) dealloc
{
arraySelectorItems = NULL;
[[NSNotificationCenter defaultCenter] removeObserver:self name:(NSString*)selectItemNotificationName object:NULL];
}
#end
From your code in the quetion I think you can try this:
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(selectedItem:) name:#"NotificationName" object:NULL];
[self.view changedProperty]; // method of your Sender class
}
It seems like your code should work. Make sure the notification is on the main thread and the workflow is as follows:
Add listener to notification center
Initiate sender
Send notification
You can be sure that it is on the main thread with:
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] post...];
});
Couple things I would change:
remove yourself from NSNotificationCenter in -(void)dealloc instead
of -(void)viewDidUnload. viewDidUnload will be deprecated, and
dealloc could get called without viewDidUnload.
For Notifications, I like to store the name in an external constant
to make sure that I don't typo the string:
//header.h
extern NSString *const notificationName;
//implementation.m
NSString *const notificationName = #"notification";
Ok, I've solved the problem. The piece of code above is not enough to understand, why it has not been working. The object of class vcReservationSelectRoom was temporary and it had been destroyed before sending notification from any vRoomSelectorItem. Sorry for my mistake of not showing enough code to solve this problem. And thank you all for helping.
Related
My app developed in Xcode with Objective-C should ask for the camera permission in order to reply to a SIP video call.
Although i wrote the Privacy - Camera Usage Description Key into my info.plist file the app only asks for the microphone permission and not for the camera permission and when I start a video call it crash.
This is my info.plist file:
My info.plist file
Also, If I go to app settings in iOS Settings there is no camera permission switch.
Update with code as requested
To make a video call i use the ABTO VoIP SDK.
AppDelegate.h
#import <UIKit/UIKit.h>
#import <AbtoSipClientWrapper/AbtoSipPhoneObserver.h>
#import "Global.h"
#include "GenDefs.h"
#define kNotifKey #"key"
#define kNotifKey_IncomingCall #"icall"
#define kNotifKey_IncomingMsg #"imsg"
#define kNotifCall_SessionId #"sid"
#define kNotifCall_RemoteInfo #"rinfo"
#define kNotifKey_IncomingIm #"iim"
#interface ImMessage : NSObject {
#public
NSString *from;
NSString *to;
NSString *text;
BOOL isRead;
}
#end
#interface AppDelegate : UIResponder <UIApplicationDelegate, AbtoPhoneInterfaceObserver> {
#public
UINavigationController *navController;
UILocalNotification *lastCallNotification;
BOOL checkIconLaunch;
NSMutableArray *imMessages;
}
+ (AppDelegate *)sharedInstance;
#property (readwrite,nonatomic) AbtoPhoneInterface* phone;
#property (retain, nonatomic) UIWindow *window;
#property (retain, nonatomic) UINavigationController *navController;
#property (strong, nonatomic) UILocalNotification *lastCallNotification;
#property (nonatomic) BOOL checkIconLaunch;
#property (nonatomic) BOOL connected;
- (void)addMessage:(ImMessage *)message;
- (NSMutableArray *)getIMs;
- (void)restoreIms;
- (void)storeIms;
#end
AppDelegate.m
#import "AppDelegate.h"
#interface AppDelegate () {
}
#end
#implementation AppDelegate
#synthesize phone;
+ (AppDelegate *)sharedInstance{
return (AppDelegate *)[UIApplication sharedApplication].delegate;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
phone = [AbtoPhoneInterface new];
[phone initialize:self];
return YES;
}
#pragma mark - UISceneSession lifecycle
- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return [[UISceneConfiguration alloc] initWithName:#"Default Configuration" sessionRole:connectingSceneSession.role];
}
- (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet<UISceneSession *> *)sceneSessions {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
- (void)applicationWillTerminate:(UIApplication *)application {
[phone deinitialize];
}
#pragma mark Abto SIP SDK delegate
- (void)onRegistered:(NSInteger)accId {
//[[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_PHONE_EVENT object:#(PhoneEventsRegSuccess)];
}
- (void)onRegistrationFailed:(NSInteger)accId statusCode:(int)statusCode statusText:(NSString*)statusText {
// [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_PHONE_EVENT object:#(PhoneEventsRegFailed)];
}
- (void)onUnRegistered:(NSInteger)accId {
// [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_PHONE_EVENT object:#(PhoneEventsUnregSuccess)];
}
- (void)onRemoteAlerting:(NSInteger)accId statusCode:(int)statusCode {
// [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_PHONE_EVENT object:#(PhoneEventsRemoteAlerting)];
}
- (void)onIncomingCall:(NSInteger)callId remoteContact:(NSString *)remoteContact {
[[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_CALL_EVENT object:#(CallEventsIncoming) userInfo:#{CALL_ID_ARGUMENT:#(callId), CONTACT_ARGUMENT:remoteContact}];
}
- (void)onCallConnected:(NSInteger)callId remoteContact:(NSString *)remoteContact {
// [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_CALL_EVENT object:#(CallEventsConnected) userInfo:#{CALL_ID_ARGUMENT:#(callId)}];
}
- (void)onCallDisconnected:(NSInteger)callId remoteContact:(NSString *)remoteContact statusCode:(NSInteger)statusCode message:(NSString *)message {
// [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_CALL_EVENT object:#(CallEventsDisconnected) userInfo:#{CALL_ID_ARGUMENT:#(callId), STATUS_ARGUMENT:#(statusCode)}];
}
- (void)onCallAlerting:(NSInteger)callId statusCode:(int)statusCode {
// [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_CALL_EVENT object:#(CallEventsAlerting) userInfo:#{CALL_ID_ARGUMENT:#(callId), STATUS_ARGUMENT:#(statusCode)}];
}
- (void)onPresenceChanged:(NSString *)uri status:(PhoneBuddyStatus)status note:(NSString *)note {
}
- (void)onCallHeld:(NSInteger)callId state:(BOOL)state {
}
- (void)onToneReceived:(NSInteger)callId tone:(NSInteger)tone {
}
- (void)onTextMessageReceived:(NSString *)from to:(NSString *)to body:(NSString *)body {
}
- (void)onTextMessageStatus:(NSString *)address reason:(NSString *)reason status:(BOOL)status {
}
- (void)onTransferStatus:(NSInteger)callId statusCode:(int)statusCode message:(NSString *)message {
// [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_CALL_EVENT object:#(CallEventsTransfering) userInfo:#{CALL_ID_ARGUMENT:#(callId), STATUS_ARGUMENT:#(statusCode), MESSAGE_ARGUMENT:message}];
}
- (void)onZrtpSas:(NSInteger)callId sas:(NSString *)sas {
// [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_CALL_EVENT object:#(CallEventsZrtpSas) userInfo:#{CALL_ID_ARGUMENT:#(callId), MESSAGE_ARGUMENT:sas}];
}
- (void)onZrtpSecureState:(NSInteger)callId secured:(BOOL)secured {
NSLog(#"ZRTP secured = %#", secured ? #"YES" : #"NO");
// [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_CALL_EVENT object:#(CallEventsZrtpSecureState) userInfo:#{CALL_ID_ARGUMENT:#(callId), STATUS_ARGUMENT:#(secured)}];
}
- (void)onZrtpError:(NSInteger)callId error:(NSInteger)error subcode:(NSInteger)subcode {
NSLog(#"ZRTP error = %ld(subcode = %ld)", (long)error, (long)subcode);
// [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_CALL_EVENT object:#(CallEventsZrtpSecureState) userInfo:#{CALL_ID_ARGUMENT:#(callId), STATUS_ARGUMENT:#(error)}];
}
#end
VideoCallViewController.h
This is the "scene" presented when a SIP call is coming.
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
NS_ASSUME_NONNULL_BEGIN
#interface VideoCallViewController : UIViewController {
BOOL isRecording;
BOOL enableSpeaker;
BOOL isFrontCamera;
BOOL isVideoMute;
BOOL sendingVideo;
}
#property (weak, nonatomic) IBOutlet UIImageView *imageViewRemoteVideo;
#property (weak, nonatomic) IBOutlet UIButton *buttonPick;
#property (weak, nonatomic) IBOutlet UIButton *buttonHangUp;
#property (weak, nonatomic) IBOutlet UIButton *buttonHangUpLadge;
#property(nonatomic, retain) NSString *number;
#property(nonatomic, assign) NSInteger callId;
#property(nonatomic, assign) BOOL incoming;
- (IBAction)onButtonClick:(UIButton *)sender;
#end
NS_ASSUME_NONNULL_END
VideoCallViewController.m
#import "VideoCallViewController.h"
#import <AVFoundation/AVCaptureOutput.h>
#import <AVFoundation/AVCaptureDevice.h>
#import <AVFoundation/AVCaptureInput.h>
#import <AVFoundation/AVMediaFormat.h>
#import <QuartzCore/QuartzCore.h>
#define ACTION_SPEAKER_ON #"Turn Speaker On"
#define ACTION_SPEAKER_OFF #"Turn Speaker Off"
#define ACTION_OPEN_DTMF #"Send DTMF"
#define ACTION_START_RECORDING #"Start Recording"
#define ACTION_STOP_RECORDING #"Stop Recording"
#define ACTION_SHOW_RTT #"Show RTT"
#define kColorsDarkBlack [NSArray arrayWithObjects: \
(id)[[UIColor colorWithRed:.1f green:.1f blue:.1f alpha:0.7] CGColor], \
(id)[[UIColor colorWithRed:0.f green:0.f blue:0.f alpha:0.7] CGColor], \
nil]
#define kColorsBlue [NSArray arrayWithObjects: \
(id)[[UIColor colorWithRed:.0f green:.0f blue:.5f alpha:0.7] CGColor], \
(id)[[UIColor colorWithRed:0.f green:0.f blue:1.f alpha:0.7] CGColor], \
nil]
#define kColorsLightBlack [NSArray arrayWithObjects: \
(id)[[UIColor colorWithRed:.2f green:.2f blue:.2f alpha:0.7] CGColor], \
(id)[[UIColor colorWithRed:.1f green:.1f blue:.1f alpha:0.7] CGColor], \
(id)[[UIColor colorWithRed:0.f green:0.f blue:0.f alpha:0.7] CGColor], \
nil]
#interface VideoCallViewController ()
#end
#implementation VideoCallViewController {
NSInteger dtmfLen;
}
#synthesize imageViewRemoteVideo;
#synthesize buttonPick;
#synthesize buttonHangUp;
#synthesize buttonHangUpLadge;
- (id)init {
self = [super init];
if (self) {
isRecording = NO;
enableSpeaker = YES;
dtmfLen = 0;
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(onPhoneNotification:) name:NOTIFICATION_PHONE_EVENT object:nil];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(onCallNotification:) name:NOTIFICATION_CALL_EVENT object:nil];
[UIDevice currentDevice].proximityMonitoringEnabled = YES;
AbtoPhoneInterface* phone = [AppDelegate sharedInstance].phone;
[phone setRemoteView:self.imageViewRemoteVideo];
// [phone setLocalView:viewLocalVideo];
if (self.incoming) {
// labelStatus.text = #"Incoming video call from";//NSLocalizedString(#"INVIDEOCALL_KEY", #"");
buttonHangUp.hidden = NO;
buttonPick.hidden = NO;
buttonHangUpLadge.hidden = YES;
} else {
self.callId = [phone startCall:self.number withVideo:YES];
// labelStatus.text = #"Dialing";//NSLocalizedString(#"VIDEOCALL_KEY", #"");
// buttonPick.hidden = YES;
// buttonHangUp.hidden = YES;
buttonHangUpLadge.hidden = NO;
}
/* labelRemoteParty.text = self.number;
labelRemoteParty.hidden = NO;
buttonActions.hidden = YES;
stopVideoButton.hidden = YES;
switchCameraButton.hidden = YES; */
// imageViewRemoteVideo.hidden = YES;
// viewLocalVideo.hidden = YES;
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if (self.callId == kInvalidCallId) {
[self closeView];
}
}
- (void)onCallNotification:(NSNotification *)notification {
}
- (void)onPhoneNotification:(NSNotification *)notification {
}
- (void)closeView {
/* if (self == [ApplicationDelegate.navController topViewController])
[ApplicationDelegate.navController popViewControllerAnimated:YES];
DLog(#"closeView"); */
}
- (IBAction)onButtonClick:(UIButton *)sender {
AbtoPhoneInterface* phone = [AppDelegate sharedInstance].phone;
if(sender == buttonHangUp || sender== buttonHangUpLadge) {
[phone hangUpCall:self.callId status:486]; /* TODO: 0 - use defalt status */
} else if(sender == buttonPick) {
[phone answerCall:self.callId status:200 withVideo:YES];
}
}
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController {
NSString* vcNumber;
NSInteger vcCallId;
BOOL vcIncoming;
}
- (void)viewDidLoad {
[super viewDidLoad];
AbtoPhoneConfig* config = [AppDelegate sharedInstance].phone.config;
// [config loadFromUserDefaults:SETTINGS_KEY];
config.regUser = #"myUsernameHere";
config.regPassword = #"myPassHere";
config.regDomain = #"sip.antisip.com";
[AppDelegate.sharedInstance.phone finalizeConfiguration];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(onCallNotification:) name:NOTIFICATION_CALL_EVENT object:nil];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(onCallNotification:) name:NOTIFICATION_CALL_EVENT object:nil];
}
- (void)onCallNotification:(NSNotification *)notification {
NSLog(#"Inizializzare CAll view");
NSInteger status = [[notification object] integerValue];
if (status == CallEventsIncoming) {
NSInteger callId = [[notification.userInfo valueForKey:CALL_ID_ARGUMENT] integerValue];
NSString *contact = [notification.userInfo valueForKey:CONTACT_ARGUMENT];
if (callId != kInvalidCallId) {
UIApplication *app = [UIApplication sharedApplication];
AppDelegate *appDelegate = [AppDelegate sharedInstance];
NSString *remotePartyNumber = [AbtoPhoneInterface sipUriUsername:contact];
UIApplicationState state = app.applicationState;
[appDelegate.phone setSpeakerphoneOn:YES];
if ((state == UIApplicationStateBackground) || (state == UIApplicationStateInactive)) {
UILocalNotification *localNotification = [UILocalNotification new];
if (localNotification) {
localNotification.alertBody = [NSString stringWithFormat:#"%# %#", remotePartyNumber, #"calling"];
// localNotif.soundName = UILocalNotificationDefaultSoundName;
localNotification.applicationIconBadgeNumber = ++app.applicationIconBadgeNumber;
localNotification.repeatInterval = 0;
NSDictionary *userInfo = #{ kNotifKey: kNotifKey_IncomingCall,
kNotifCall_SessionId : #(callId),
kNotifCall_RemoteInfo: contact };
localNotification.userInfo = userInfo;
[[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
// ApplicationDelegate.lastCallNotification = localNotification;
}
} else {
vcNumber = remotePartyNumber;
vcCallId = callId;
vcIncoming = YES;
[self performSegueWithIdentifier:#"segue1" sender:self];
/* VideoCallViewController *nextController = [appDelegate.phone isVideoCall:callId] ? [VideoCallViewController new] : [VideoCallViewController new];
nextController.number = remotePartyNumber;
nextController.callId = callId;
nextController.incoming = YES;
[appDelegate.navController pushViewController:nextController animated:YES]; */
}
}
} else if (status == CallEventsDisconnected) {
// ApplicationDelegate.lastCallNotification = nil;
}
}
- (void)onPhoneNotification:(NSNotification *)notification {
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([[segue identifier] isEqualToString:#"segue1"]) {
VideoCallViewController *nextController = [segue destinationViewController];
nextController.number = vcNumber;
nextController.callId = vcCallId;
nextController.incoming = vcIncoming;
}
}
#end
The call code is fine, because I tested it multiple times. The issue is that the app does not ask for the camera permission.
Apple developer sample of Reachability cause Memory Leak when turning off wifi during play offline music (using this code) in my app and it got stuck line I mentioned bottom, It may cause by that Player code because log says [__NSCFString reachabilityDidChange:]: unrecognized selector
[[NSNotificationCenter defaultCenter] postNotificationName:kReachabilityChangedNotification object:noteObject];
in this method:
static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info)
{
#pragma unused (target, flags)
NSCAssert(info != NULL, #"info was NULL in ReachabilityCallback");
NSCAssert([(__bridge NSObject*) info isKindOfClass: [CDVReachability class]], #"info was wrong class in ReachabilityCallback");
CDVReachability* noteObject = (__bridge CDVReachability *)info;
// Post a notification to notify the client that the network reachability changed.
[[NSNotificationCenter defaultCenter] postNotificationName: kReachabilityChangedNotificationString object: noteObject];
}
Here is log:
2015-04-12 19:52:03.416 HelloCordova[4094:1250289] -[__NSCFString reachabilityDidChange:]: unrecognized selector sent to instance 0x174232820
And reachabilityDidChange is in this file
#import "ReachabilityManager.h"
#import "Reachability.h"
#interface ReachabilityManager ()
#property NetworkStatus previousReachability;
#end
#implementation ReachabilityManager
- (id) init {
self = [super init];
if (self) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(reachabilityDidChange:)
name:kReachabilityChangedNotification
object:nil];
self.previousReachability = -1;
}
return self;
}
- (void) reachabilityDidChange:(NSNotification *)notification {
NSLog(#"reachabilityDidChange!");
CDVReachability * r = [notification object];
NetworkStatus ns = [r currentReachabilityStatus];
if (self.delegate && [self.delegate respondsToSelector:#selector(reachabilityDidChangeFrom:to:)]) {
[self.delegate reachabilityDidChangeFrom:self.previousReachability to:ns];
}
self.previousReachability = ns;
}
#end
I don't know is that correct but I try this:
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:kReachabilityChangedNotification object:noteObject];
});}
and even this:
// We're on the main RunLoop, so an NSAutoreleasePool is not necessary, but is added defensively
// in case someon uses the Reachability object in a different thread.
#autoreleasepool {
Reachability* noteObject = (__bridge Reachability*)info;
// Post a notification to notify the client that the network reachability changed.
[[NSNotificationCenter defaultCenter] postNotificationName:kReachabilityChangedNotification object:noteObject];
}
Hi i am trying to pass the user.id and user.name from loginViewFetchedUserInfo: to my menuViewController, profileViewController and settingViewController so far i have sent the info to profileViewController with:
// this method will be called when the user information has been fetched
- (void)loginViewFetchedUserInfo:(FBLoginView *)loginView user:(id<FBGraphUser>)user
{
// self.profilePictureView.profileID = user.id;
//self.FBProfilePicture.profileID = user.id;
_profilePicture = user;
_FBNameString = user.name;
NSLog(#"%#, name from Login", _FBNameString);
[self pushViewController:user.name andProfilePicture:_profilePicture];
}
- (void)pushViewController:(NSString *)userName andProfilePicture:(id<FBGraphUser>)profilePicture
{
// MenuViewController *menu = [self.storyboard instantiateViewControllerWithIdentifier:#"MenuViewController"];
// [menu setFBName:userName];
// [menu setFBProfilePic:profilePicture];
//
// SettingViewController *setting = [self.storyboard instantiateViewControllerWithIdentifier:#"SettingViewController"];
// [setting setFBName:userName];
// [setting setFBProfilePic:profilePicture];
// NSLog(#"%#",profilePicture);
// [self.navigationController pushViewController:controller animated:NO];
}
and i can only receive the info in the profileViewController and not the other i have put setters and getters i'm using protocols but i'm not able to get it to another viewController
In general you method should be like this.(you may need to tweak as per requirement)
// this method will be called when the user information has been fetched
-(void)loginViewFetchedUserInfo:(FBLoginView *)loginView user:(id<FBGraphUser>)user{
// self.profilePictureView.profileID = user.id;
//self.FBProfilePicture.profileID = user.id;
_profilePicture = user.picture;//assuming you may be having picture property for object user
_FBNameString = user.name;
NSLog(#"%#, name from Login", _FBNameString);
//POST NOTIFICATION with desire object here its "user"
[[NSNotificationCenter defaultCenter] postNotificationName:#"POSTLOGININFO" object:user];
//uncomment if you want this, ...depends on you
//[self pushViewController:user.name andProfilePicture:_profilePicture];
}
Now update init method of your menuViewController.m, profileViewController.m and settingViewController.m class like below
-(id) init
{
self = [super init];
if (!self)
return nil;
//Your custom code
//get registered for POSTLOGININFO notification so that selector method get called when you post notification with name POSTLOGININFO
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(gotLoginInfo:)
name:#"POSTLOGININFO"
object:nil];
return self;
}
Add new method gotLoginInfo: to each of your menuViewController.m, profileViewController.m and settingViewController.m
-(void)gotLoginInfo:(NSNotification *)notification{
//Assuming FBGraphUser class have all required properties
FBGraphUser *user = (FBGraphUser *)[notification object];
// save user.id and user.name to your class local variable
NSLog(#"UserID::%# and username::%#",user.id,user.name);
}
-(void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"POSTLOGININFO" object:nil];
}
remove notification observer once you are done by using
"[[NSNotificationCenter defaultCenter] removeObserver:self name:#"POSTLOGININFO" object:nil];". Also be sure to have valid objects of your class menuViewController, profileViewController and settingViewController before loginViewFetchedUserInfo: get called
You can use NSNotification.
Example
There is a method named myTestNotificationReceived which is implemented in myClassA. Now I want to call this method from another class myClassB. Below is the code how I can do this using NSNotificationCenter.
#implementation myClassA
- (void) dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
- (id) init
{
self = [super init];
if (!self) return nil;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(myTestNotificationReceived:)
name:#"myTestNotification"
object:nil];
return self;
}
- (void) myTestNotificationReceived:(NSNotification *) notification
{
if ([[notification name] isEqualToString:#"myTestNotification"])
NSLog (#"Notification is successfully received!");
}
#end
Now I want to call the method myTestNotification from myClassB.
#implementation myClassB
- (void) dealloc{
[super dealloc];
}
- (id) init
{
self = [super init];
if (!self) return nil;
return self;
}
- (void) myMethod
{
// All instances of myClassA will be notified
[[NSNotificationCenter defaultCenter]
postNotificationName:#"myTestNotification"
object:self];
}
#end
Now you can add as many observer in your different classes.
I am trying to separate my GUI and my Logic...For example, i have one class which calculates something (calc.h/calc.m). And i have my GUI (viewController.h/viewController.m)...Now i want to update one Element of the GUI from another class... I already tried it with a Singleton, like this:
calc.m:
viewController *con = [viewController sharedInstance];
con.download.text = #"It Works";
viewController.m:
+ (id)sharedInstance {
static id sharedInstance;
#synchronized(self) {
if (!sharedInstance)
sharedInstance = [[viewController alloc] init];
return sharedInstance;
}
}
But it does´t work...
UPDATE:
in my ViewController:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(receiveNotification:)
name:#"UpdateDownloadLabel"
object:nil];
- (void) receiveNotification:(NSNotification *) notification
{
NSDictionary* userInfo = notification.userInfo;
if ([[notification name] isEqualToString:#"Update"])
{
download.text = [userInfo valueForKey:#"Test"];
}
}
And in my other class i post the notification like this:
[[NSNotificationCenter defaultCenter]
postNotificationName:#"UpdateDownloadLabel"
object:nil userInfo:info];
But it doesn't work...
That's not a proper use of a singleton. If you need to notify your UI from your model you have these options:
- delegation
- Local Notification
- KVO
The general rule is to keep your logic decoupled from your presentation, therefore your calc class shouldn't really know that a label named download exists.
Example: How to use notification.
In classA.h file
extern NSString * const ClassADidViewNotification;
In classA.m file
NSString * const ClassADidViewNotification = #"ClassADidViewNotification";
Register for notification in classA.m :-
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserverForName: XXFooDidBarNotification
object:nil
queue:nil
usingBlock:^(NSNotification *notification)
{
NSLog(#"notification.object: %#", notification.object);
}
];
Post Notification:-
ClassB.m
[[NSNotificationCenter defaultCenter] postNotificationName: ClassADidViewNotification object:nil];
I am posting notification from UIViewController object to UIView object. Notification is called but its method "playSound" is not called.
Below is my code and Thanks in Advance :
#interface SettingsViewController : UIViewController <MFMailComposeViewControllerDelegate>
{
MFMailComposeViewController *mailComposer;
}
- (IBAction)btnSoundClicked:(id)sender {
if(self.btnSound.on)
{
NSLog(#"Swith On");
[[NSNotificationCenter defaultCenter] postNotificationName:#"soundStatus" object:self.btnSound];
}
else
{
NSLog(#"Switch Off");
}
}
#interface IAPuzzleBoardView : UIView <AVAudioPlayerDelegate> {
}
- (void)movingThisTile:(CGPoint)tilePoint {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playSound:)
name:#"soundStatus"
object:nil];
}
-(void) playSound : (NSNotification *) notification
{
if ([[notification name] isEqualToString:#"soundStatus"])
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"move" ofType:#"wav"];
theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.delegate = self;
[theAudio play];
}
}