I'm using a EKEventEditViewController which I'm able to populate with the info I need. I'm granted access to the Calendars and everything. My problem is when I click "Cancel" nothing happens. And when I click "Done" I get an error saying that No calendar has been set, no date has been set and "The event does not belong to that event store".
I don't think that my didCompleteWithAction delegate method is being called.
My viewController conforms to:
#interface EventoViewController : UIViewController <EKEventEditViewDelegate>
When I try to set self as delegate I get the error:
sending EventoViewController *const__strong' to parameter of incompatible type 'id<UINavigationControllerDelegate>'
Original Code .h
#import <UIKit/UIKit.h>
#import <EventKit/EventKit.h>
#import <EventKitUI/EventKitUI.h>
#interface EventoViewController : UIViewController <EKEventEditViewDelegate>
#property (weak, nonatomic) IBOutlet UILabel *eventDetailTitleLabel;
#property (weak, nonatomic) IBOutlet UILabel *eventDetailDateLabel;
#property (weak, nonatomic) IBOutlet UILabel *eventDetailDescriptionLabel;
- (IBAction)closeModalView:(id)sender;
- (IBAction)addEventToNative:(id)sender;
#end
Original .m
#import "EventoViewController.h"
#implementation EventoViewController
#synthesize eventDetailTitleLabel, eventDetailDateLabel, eventDetailDescriptionLabel;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad { [super viewDidLoad]; }
- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; }
- (IBAction)closeModalView:(id)sender { [self dismissModalViewControllerAnimated:YES]; }
- (IBAction)addEventToNative:(id)sender {
NSLog(#"Clicked ");
EKEventStore *eventStore = [[EKEventStore alloc] init];
if([eventStore respondsToSelector:#selector(requestAccessToEntityType:completion:)]) {
// iOS 6 and later
[eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
// perform the main thread here to avoid any delay. normally seems to be 10 to 15 sec delay.
[self performSelectorOnMainThread: #selector(presentEventEditViewControllerWithEventStore:) withObject:eventStore waitUntilDone:NO];
if (granted){
NSLog(#"We are granted to access Calendars!");
//---- codes here when user allow your app to access theirs' calendar.
}
else {
//---- code for no permission
NSLog(#"We have no permission to access calendars!");
}
}];
}
}
- (void)presentEventEditViewControllerWithEventStore:(EKEventStore*)eventStore {
EKEventEditViewController* eventEditVC = [[EKEventEditViewController alloc] init];
eventEditVC.eventStore = eventStore;
EKEvent* event = [EKEvent eventWithEventStore:eventStore];
event.title = self.eventDetailTitleLabel.text;
event.startDate = [NSDate date];
event.endDate = [NSDate date];
event.URL = [NSURL URLWithString:#"http://portalsatuat.plataforma.sat.gob.mx/m/sp/paginas/home.aspx"];
event.notes = #"Evento SAT";
event.allDay = YES;
eventEditVC.event = event;
//eventEditVC.delegate = (id)self;
[self presentViewController:eventEditVC animated:YES completion:nil];
}
- (void)eventEditViewController:(EKEventEditViewController *)controller didCompleteWithAction:(EKEventEditViewAction)action {
NSLog(#"Clicked Cancel or Done");
[self dismissModalViewControllerAnimated:YES];
}
- (void)eventViewController:(EKEventViewController *)controller didCompleteWithAction:(EKEventViewAction)action {
NSLog(#"No se que esta pasando aqui!");
}
- (void)viewDidUnload {
[self setEventDetailTitleLabel:nil];
[self setEventDetailDateLabel:nil];
[self setEventDetailDescriptionLabel:nil];
[super viewDidUnload];
}
#end
You need to assign self in your view controller class to the editViewDelegate property on the controller - the EKEventEditViewController class is a subclass of UINavigationController so the inherited delegate property is for handling navigation events. Hope that helps.
- (void)presentEventEditViewControllerWithEventStore:(EKEventStore*)eventStore {
EKEventEditViewController* eventEditVC = [[EKEventEditViewController alloc] init];
eventEditVC.eventStore = eventStore;
// Add this line:
eventEditVC.editViewDelegate = self;
Related
I have a custom UIWebView (EpubWebView), with a custom NSURLCache (EpubCache) for handling requests.
i created a custom delegate for handling request.
EpubCache.h
#protocol EpubCacheDelegate <NSObject>
#required
- (NSCachedURLResponse *)hadleRequest:(NSURLRequest *)request;
#end
#interface EpubCache : NSURLCache
#property (nonatomic, weak) id <EpubCacheDelegate> cacheDelegate;
#end
EpubCache.m
import "EpubCache.h"
#interface EpubCache ()
#end
#implementation EpubCache
- (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request
{
return [self.cacheDelegate hadleRequest:request];
}
#end
EpubWebView .h
#interface EpubWebView : UIWebView <UIWebViewDelegate, EpubCacheDelegate>
#property (strong, nonatomic) EpubCache *mLocalCache;
#end
EpubWebView.m
- (void) localInit
{
self.mLocalCache = [[EpubCache alloc] init];
self.mLocalCache.cacheDelegate = self;
[NSURLCache setSharedURLCache:self.mLocalCache];
}
- (NSCachedURLResponse *)hadleRequest:(NSURLRequest *)request
{
// return handled request
}
on the other hand i have a navigationcontroller with a tableview and the destination view controller have this webview.
when i ran the app and click on an item in tableview, everything is fine and delegate works as expected.
if i click back and click on other item in tableview, things goes wrong, the cachedResponseForRequest getting called but the hadleRequest wont, i checked and findout that the delegate is null!
i can not figure out what is happening here.
any help would be appreciated.
UPDATE 1
EpubWebView.m
- (id)init
{
self = [super init];
if (self)
{
[self localInit];
}
return self;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if(self)
{
[self localInit];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if(self)
{
[self localInit];
}
return self;
}
UPDATE 2
the segue of the tableview that bring up the view controller that contain EpubWebView
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSIndexPath *indexPath = [self.collectionView indexPathForCell:sender];
BookViewController *bookController = segue.destinationViewController;
bookController.mBook = booksList[indexPath.row];
}
and BookViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
mWebView = [[EpubWebView alloc] initWithFrame:self.mainView.frame];
[self.mainView addSubView:mWebView];
[mWebView setBook:self.mBook];
}
You need to make a few modifications. First, remove your "localInit" method, then create a new function in EPubWebView:
- (void) setCache: (EpubCache *)localCache
{
localCache.cacheDelegate = self;
}
Now, you can create and hold onto your cache in your BookViewController via these lines in the .m file:
#interface BookViewController ()
#property (strong, nonatomic) EpubCache *mLocalCache;
#end
and change your BookViewController's viewDidLoad method to look like:
- (void) viewDidLoad {
self.mLocalCache = [[EpubCache alloc] init];
// only need to do this once, at viewDidLoad time
[NSURLCache setSharedURLCache:self.mLocalCache ];
[super viewDidLoad];
mWebView = [[EpubWebView alloc] initWithFrame:self.mainView.frame];
[mWebView setCache:self.mLocalCache];
[self.mainView addSubView:mWebView];
[mWebView setBook:self.mBook];
}
So perhaps this is a beginner's mistake and super easy to you guys, but i really do not know how to solve it,really appreciate for any suggestions:
Right Now:
1: I have to ViewController: EnterCommandViewController and DetectionViewController
2: I wrote Delegate protocol in EnterCommandViewController and set DetectionViewController as its delegate.
3: About delegate: I have a inputTextField in the EnterCommandView and a "Save" bar button item on the top toolbar in this view. Once I click the save , current view will be dismissed and return back to DetectionView and show the NSString just entered in the UILabel in DetectionView.
Finally, My question is that Why After I alloc and init a EnterCommandViewController instance , that is enterCVS, the instance is still nil as show in end of my post.
Code:
EnterCommandViewController.h
#import <UIKit/UIKit.h>
#import "RscMgr.h"
#protocol EnterCommandDelegate <NSObject>
#optional
-(void) commandEntered:(NSString*)command;
#end
#interface EnterCommandViewController : UIViewController <RscMgrDelegate,EnterCommandDelegate>
{
RscMgr* rscMgr;
IBOutlet UITextField *inputTextField;
// DetectionViewController* detectionViewController;
// __unsafe_unretained id<EnterCommandDelegate> delegate;
}
-(void)sendMessage:(NSString*)message;
-(id)initWithDelegate:(id)delegateToBe;
- (IBAction)cancelPressed;
- (IBAction)savePressed;
#property (nonatomic,weak) id<EnterCommandDelegate> delegate; //assign replaced
#end
EnterCommandVIewController.m
#import "EnterCommandViewController.h"
#import "DetectionViewController.h"
#interface EnterCommandViewController () <UITextFieldDelegate>
{
#private
BOOL connected;
}
#end
#implementation EnterCommandViewController
#synthesize delegate;
- (void)viewDidLoad {
[super viewDidLoad];
rscMgr = [[RscMgr alloc] init];
[rscMgr setDelegate:self];
// Do any additional setup after loading the view, typically from a nib.
[inputTextField becomeFirstResponder];
}
-(id)initWithDelegate:(id)delegateToBe{
if(self = [super init]){
delegate = delegateToBe;
}
return self;
}
-(void) viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
inputTextField.delegate = self;
}
-(void) viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
inputTextField.delegate = nil;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - UITextFieldDelegate Methods
-(BOOL) textFieldShouldReturn:(UITextField *)textField{
[self sendMessage:textField.text];
textField.text = nil;
return NO;
}
#pragma mark - Serial Tx/Rx Methods Implementation
-(void) sendMessage:(NSString *)message{
if(connected == YES) {
[rscMgr writeString:message];
}
else{
NSLog(#"CableDisconnected!");
NSLog(#"Attempted To Send: %#",message);
}
}
- (IBAction)cancelPressed {
[self dismissViewControllerAnimated:YES completion:^{}];
}
- (IBAction)savePressed {
//is anyone listening
if([[[UIDevice currentDevice]systemVersion] compare:#"7.0" options:NSNumericSearch] != NSOrderedAscending){
NSLog(#"SYStem version > 7.0");
}
if(delegate&&[delegate respondsToSelector:#selector(commandEntered:)]){
NSLog(#"SomeMethod is listening");
[delegate commandEntered:inputTextField.text];
}
[self dismissViewControllerAnimated:YES completion:nil]; //commened: ^{}
}
#pragma mark - RscMgrDelegate Methods Implementation
-(void) cableConnected:(NSString *)protocol{
inputTextField.text = #"cableConnected";
[rscMgr setBaud:9600];
[rscMgr open];
connected = YES;
}
-(void) cableDisconnected{
inputTextField.text = #"cableDisconnected";
connected = NO;
}
-(void) readBytesAvailable:(UInt32)length{}
-(void) portStatusChanged{}
#end
DetectionViewController.h
#import <UIKit/UIKit.h>
#import "EnterCommandViewController.h"
#interface DetectionViewController : UIViewController <EnterCommandDelegate>{
}
- (IBAction)showSettings:(UIBarButtonItem *)sender;
#property (nonatomic, strong) EnterCommandViewController* enterCVC;
#property (nonatomic, strong) IBOutlet UILabel *showReceivedCommand;
#end
DetectionViewController.m
#import <Foundation/Foundation.h>
#import "DetectionViewController.h"
#import "EnterCommandViewController.h"
#implementation DetectionViewController
#synthesize showReceivedCommand;
#synthesize enterCVC;
- (IBAction)showSettings:(UIBarButtonItem *)sender {
}
-(void) viewDidLoad{
[super viewDidLoad];
if(showReceivedCommand){
showReceivedCommand.text=#"Initial text";
NSLog(#"UILAbel in ViewDidload is not nil");
}else {
NSLog(#"UILAbel in viewDidload is nil");
}
enterCVC = [[EnterCommandViewController alloc] init];
if(enterCVC.delegate) NSLog(#"X nil");
[enterCVC setDelegate:self];
}
#pragma mark - EnterCommandDelegate function(s)
-(void)commandEntered:(NSString *)command{
dispatch_async(dispatch_get_main_queue(), ^{
if(showReceivedCommand){
NSLog(#"UILabel is not nil");
}else{NSLog(#"UILabel is nil");}
showReceivedCommand = [[UILabel alloc] init];
NSLog(#"command received: %#",command);
showReceivedCommand.text = command;
[showReceivedCommand setNeedsDisplay];
NSLog(#"text in showReceivedCommand is %#",showReceivedCommand.text);
});
}
#end
I set a break point at DetectionViewController.n --> ViewDidLoad() --> [enterCVC setDelegate:self];
I got:
self DetectionViewController * 0x15c50e850 0x000000015c50e850
UIViewController UIViewController
showReceivedCommand UILabel * 0x15c510650 0x000000015c510650
enterCVC EnterCommandViewController * 0x15c611360 0x000000015c611360
showReceivedCommand UILabel * 0x15c510650 0x000000015c510650
enterCVC EnterCommandViewController * 0x15c611360 0x000000015c611360
UIViewController UIViewController
rscMgr RscMgr * nil 0x0000000000000000
inputTextField UITextField * nil 0x0000000000000000
connected BOOL NO false
delegate id 0x0 0x0000000000000000
enterCVC = [[EnterCommandViewController alloc] init]
Try changing that to....
enterCVC = [[EnterCommandViewController alloc] initWithDelegate:self];
I am trying to set up a countdown timer. I have two view controllers: ViewController and EditViewController. ViewController has two labels hours and minutes. EditViewController has a UIDatePicker and a save button. When the user selects a time on the UIDatePicker and hits save, they are redirected back to the ViewController and the hour and minute labels are populated with the difference between the selected time and current time. This is automatically updated until the difference is 0. I have having issues trying to get the hour and minutes to display correctly on the ViewController labels. Here is my code:
ViewController.m
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.hourLabel.text = self.hourText;
self.minuteLabel.text = self.minuteText;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
EditViewController.h
#interface EditViewController : UIViewController
#property (weak, nonatomic) IBOutlet UIDatePicker *datePicker;
#property (weak, nonatomic) IBOutlet NSString *currentTimeString;
#property (weak, nonatomic) IBOutlet NSString *endTimeString;
- (IBAction)saveButton:(id)sender;
- (IBAction)cancelButton:(id)sender;
-(void)updateTime;
#end
EditViewController.m
#import "EditViewController.h"
#import "ViewController.h"
#interface EditViewController ()
#end
#implementation EditViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)saveButton:(id)sender
{
NSCalendar *now = [NSCalendar autoupdatingCurrentCalendar];
NSInteger currentTime = (NSHourCalendarUnit | NSSecondCalendarUnit);
self.datePicker.date = [now dateFromComponents:[now components:currentTime fromDate:self.datePicker.date]];
NSTimer *timer;
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(updateTime) userInfo:nil repeats:YES];
[self dismissViewControllerAnimated:YES completion:nil];
}
-(void)updateTime
{
NSInteger timeLeft = ((NSInteger)[self.datePicker.date timeIntervalSinceNow]);
NSInteger minutes = (timeLeft / 60) % 60;
NSInteger hours = (timeLeft / 3600) % 24;
ViewController *controller;
controller.hourText = [NSString stringWithFormat:#"%ldi",(long)hours];
controller.minuteText = [NSString stringWithFormat:#"%ldi",(long)minutes];
NSLog(#"The time is %ld",(long)timeLeft);
}
- (IBAction)cancelButton:(id)sender
{
[self dismissViewControllerAnimated:YES completion:nil];
}
#end
Any help is appreciated. Thanks in advance.
Have a look at here for the edited method from your code. This will full-fill your requirement.
#import "EditViewController.h"
#import "ViewController.h"
#import "AppDelegate.h"
#interface EditViewController ()
{
AppDelegate *appDelegate;
}
#end
#implementation EditViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
// Custom initialization
appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
}
return self;
}
-(void)updateTime
{
NSInteger timeLeft = ((NSInteger)[self.datePicker.date timeIntervalSinceNow]);
NSInteger minutes = (timeLeft / 60) % 60;
NSInteger hours = (timeLeft / 3600) % 24;
NSString *hourText = [NSString stringWithFormat:#"%ldi",(long)hours];
NSString *minuteText = [NSString stringWithFormat:#"%ldi",(long)minutes];
[appDelegate updateTime:hourText andMinute:minuteText];
}
and finally, define a method in AppDelegate class
- (void) updateTime:(NSString *)hourStr andMinute:(NSString *)minuteStr
{
for(id obj in [self.navigationController viewControllers])
{
if([obj isKindOfClass:ViewController])
{
ViewController *vcObj = (ViewController *)obj;
vcObj.hourLabel.text = hourStr;
vcObj.minuteLabel.text = minuteStr;
}
}
}
Several issues:
ViewController.m
self.hourLabel.text = self.hourText;
self.minuteLabel.text = self.minuteText;
Should be in viewWillAppear instead of viewDidLoad. What's happening is you set the text when the app loads. viewDidLoad will only fire once for that instance of the app ever. What you're needing to do is update it when you come back from the EditViewController, right? So if you put it in viewWillAppear, it will also get called when you come back and update it for you.
The next thing:
EditViewController.m
ViewController *controller;
controller.hourText = [NSString stringWithFormat:#"%ldi",(long)hours];
controller.minuteText = [NSString stringWithFormat:#"%ldi",(long)minutes];
NSLog(#"The time is %ld",(long)timeLeft);
This code snippet is declaring a new ViewController variable (well, most of it, you're missing the = [ViewController new] part). The problem with this is that you don't do anything with this controller. ViewController is actually already in your navigation stack (I'm assuming NavigationController since you said when the user goes back), so you need to use the reference to ViewController your app has already instantiated, not create a new one since you never use this guy anywhere.
I have watched tutorials and what I have learnt, that I have implemented on a project with two viewControllers just a simple firstName, lastName practice but I don't know where to place the method setFirstName: in a facebook project that I'm doing I wish to login (that works) then it automatically goes to another viewController (that works) I just cant get the user.name to be displayed, in which facebook delegate do i call the method, I fetch the info here and place it in the property in the loginViewController
- (void)loginViewFetchedUserInfo:(FBLoginView *)loginView user:(id<FBGraphUser>)user
{
firstName = user.name;
[[self delegate] setFirstName:firstName];
}
then in the profileViewController I place this:
- (void)setFirstName:(NSString *)firstName
{
firstNameString = firstName;
}
then i assign the properties here
-(void)viewWillAppear:(BOOL)animated
{
self.firstNameLabel.text = firstNameString;
}
i think my issue is when I'm pushing to the profileViewController I'm not passing the info in the transition cause i don't use a segue I'm just pushing the viewController please help been on this issue for a week or so thanks
EDIT::
LoginViewController.m
// 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;
FBNamePass = user.name;
}
- (void)pushViewController
{
NeXtViewController *controller = [[NeXtViewController alloc] init];
controller.FBNameString = FBNamePass;
[self.navigationController pushViewController:controller animated:YES];
}
EDIT 2::
LoginViewController.h
#import <UIKit/UIKit.h>
#import <FacebookSDK/FacebookSDK.h>
#protocol passNames <NSObject>
- (void)setFBName: (NSString *)FBName;
#end
#interface ViewController : UIViewController <FBLoginViewDelegate>
#property (retain) id <passNames> delegate;
#property (strong, nonatomic) NSString *FBNamePass;
#end
LoginViewController.m
#import "ViewController.h"
#import "NeXtViewController.h"
#interface ViewController ()
#property (strong, nonatomic) IBOutlet UILabel *statusLabel;
#property (strong, nonatomic) IBOutlet UILabel *nameLabel;
#property (strong, nonatomic) IBOutlet FBProfilePictureView *profilePictureView;
#end
#implementation ViewController
#synthesize delegate, FBNamePass;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// Create a FBLoginView to log the user in with basic, email and likes permissions
// you should always ask for basic permissions when loggin the user in
FBLoginView *loginView = [[FBLoginView alloc] initWithReadPermissions:#[#"basic_info",#"email",#"user_likes"]];
// set this loginUIViewCOntroller to be the loginView button's delegate
loginView.delegate = self;
// align the button in the center horizontally
loginView.frame = CGRectMake(25, 299, 271, 50);
// align the button in the center vertically
//loginView.center = self.view.center;
// add the button to the view
[self.view addSubview:loginView];
[self pushViewController];
}
-(void)viewDidAppear:(BOOL)animated
{
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
// 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;
FBNamePass = user.name;
}
// implement the loginViewShowingLoggedInUser: delegate method to modify your app's UI for a logged-in user experoience
- (void)loginViewShowingLoggedInUser:(FBLoginView *)loginView
{
self.statusLabel.text = #"Logged in";
if ([self.statusLabel.text isEqualToString:#"Logged in"]) {
NeXtViewController *n = [self.storyboard instantiateViewControllerWithIdentifier:#"NeXt"];
[self.navigationController pushViewController:n animated:NO];
}
}
// implement the loginViewShowingLoggedOutUser: delegate method to modify your app's UI for a logged-out user experoience
- (void)loginViewShowingLoggedOutUser:(FBLoginView *)loginView
{
self.profilePictureView.profileID = nil;
self.nameLabel.text = #"";
self.statusLabel.text = #"You're not logged in";
}
// You need to override loginView:handleError in order to handle possible errors that can occur during login
- (void)loginView:(FBLoginView *)loginView handleError:(NSError *)error
{
NSString *alertMessage, *alertTitle;
// If the user should perform an action outside of you app to recover,
// the SDK will provide a message for the user, you just need to surface it.
// This conveniently handles cases like Facebook password change or unverified Facebook accounts.
if ([FBErrorUtility shouldNotifyUserForError:error]) {
alertMessage = [FBErrorUtility userMessageForError:error];
alertTitle = #"Facebook Error";
// This code will handle session closures since that happen outside of the app.
// You can take a look at our error handling guide to know more about it
// https://developers.facebook.com/docs/ios/errors
} else if ([FBErrorUtility errorCategoryForError:error] == FBErrorCategoryAuthenticationReopenSession) {
alertTitle = #"Session Error";
alertMessage = #"Your current session is no longer valid. Please log in again.";
// If the user has cancelled a login, we will do nothing.
// You can also choose to show the user a message if cancelling login will result in
// the user not being able to complete a task they had initiated in your app
// (like accessing FB-stored information or posting to Facebook)
} else if ([FBErrorUtility errorCategoryForError:error] == FBErrorCategoryUserCancelled) {
NSLog(#"user cancelled login");
// For simplicity, this sample handles other errors with a generic message
// You can checkout our error handling guide for more detailed information
// https://developers.facebook.com/docs/ios/errors
} else {
alertTitle = #"Something went wrong";
alertMessage = #"Please try again later";
NSLog(#"Unexpected error:%#",error);
}
if (alertMessage) {
[[[UIAlertView alloc] initWithTitle:alertTitle
message:alertMessage
delegate:nil
cancelButtonTitle:#"ok"
otherButtonTitles:nil] show];
}
}
- (void)pushViewController
{
NeXtViewController *controller = [[NeXtViewController alloc] init];
controller.FBNameString = FBNamePass;
[self.navigationController pushViewController:controller animated:YES];
}
ProfileViewController.h
#import <UIKit/UIKit.h>
#import <FacebookSDK/FacebookSDK.h>
#import "ViewController.h"
#interface NeXtViewController : UIViewController <passNames>
{
ViewController *view;
}
#property (strong,nonatomic) NSString *FBNameString;
#property (weak, nonatomic) IBOutlet UILabel *nameLabel;
#end
ProfileViewController.m
#import "NeXtViewController.h"
#interface NeXtViewController ()
#end
#implementation NeXtViewController
#synthesize FBNameString;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
view = [[ViewController alloc] init];
[view setDelegate:self];
self.nameLabel.text = FBNameString;
self.navigationItem.hidesBackButton = YES;
}
-(void)viewDidAppear:(BOOL)animated
{
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)setFBName:(NSString *)FBName
{
FBNameString = FBName;
}
#end
You need create property in ProfileViewController -> create instance of ProfileViewController -> set user name to instance property -> push instance of ProfileViewController:
LoginViewController.m
- (void)pushProfileViewController {
ProfileViewController *controller = [[ProfileViewController alloc] init];
controller.firstName = firstNameString;
[self.navigationController pushViewController:controller animated:YES];
}
Let's see if you guys can find the error here... because I'm really stuck right now.
DBManager.h
#protocol DBManagerDelegate <NSObject>
#optional
- (void) managerDidFinishUpdating:(id)controller;
#end
#interface DBManager : NSObject
#property (strong, nonatomic) id <DBManagerDelegate> delegate;
- (id) init;
#end
DBManager.m
#import "DBManager.h"
#implementation DBManager
- (id)init {
self = [super init];
if (self) {
[[self delegate] managerDidFinishUpdating:self];
}
return self;
}
UIViewController.h
#import <UIKit/UIKit.h>
#import "DBManager.h"
#interface DBViewController : UIViewController <DBManagerDelegate>
#property (nonatomic, retain) DBManager *manager;
#end
UIViewController.m
#import "DBViewController.h"
#implementation DBViewController
- (void)viewDidLoad
{
[super viewDidLoad];
_manager = [[DBMataroManager alloc] init];
[_manager setDelegate:self];
}
- (void)managerDidFinishUpdating:(id)controller {
NSLog(#"Manager did finish");
}
#end
You should write like this,
- (id)initWithDelegate:(id)delegate {
self = [super init];
if (self) {
_delegate = delegate;
[_delegate managerDidFinishUpdating:self];
}
return self;
}
//Call it as follow
_manager = [[DBManager alloc] initWithDelegate:self];
[_manager setDelegate:self];
The delegate method managerDidFinishUpdating: is called within init. You set yourself as the delegate after calling init.
Maybe an initWithDelegate: method would help.
- (instancetype)initWithDelegate:(id< DBManagerDelegate>)delegate {
self = [super init];
if (self) {
self.delegate = delegate;
[self.delegate managerDidFinishUpdating:self];
}
return self;
}
You are trying to use the delegate in the init, but you have not set it until the next statement. The only way to do this would be to set the delegate as part of you init statement.
-(id)initWithDelegate:(id<DBManageDelegate>)delegate {
if ((self = [super init])) {
self.delegate = delegate;
if (delegate && [delegate respondsToSelector:#selector(managerDidFinishUpdating:)]) {
[delegate performSelector:#selector(managerDidFinishUpdating:) withObject:self];
}
}
return self;
}
But if you plan to do some additional things before the manager is updated I would suggest you move all of that outside of the init, perhaps into an updateManager function like this
-(void)updateManager {
// Do the stuff that updates your manager here
if (delegate && [delegate respondsToSelector:#selector(managerDidFinishUpdating:)]) {
[delegate performSelector:#selector(managerDidFinishUpdating:) withObject:self];
}
}
..later in your app
_manager = [[DBMataroManager alloc] init];
[_manager setDelegate:self];
[_manager updateManager];