Accessing user defined delegate via multiple ViewControllers - iOS - ios

I'm using the BLE framework files that came with some hardware, but I'm only able to call the functions in my first view controller. My application has two view controllers and it is my intention to write and read BLE data in both views, using the BLEDelegate.
Everything works as expected in the first view controller, but I get no action from the BLE files in the second view controller.
This is a skeleton of my project.
BLE.h
#import <CoreBluetooth/CoreBluetooth.h>
#protocol BLEDelegate
#optional
-(void) bleDidReceiveData:(unsigned char *) data length:(int) length;
#required
#end
#interface BLE : NSObject;
#property (nonatomic,assign) id <BLEDelegate> delegate;
-(void) write:(NSData *)d;
#end
BLE.m
#import "BLE.h"
#interface BLE ()
#end
#implementation BLE
#synthesize delegate;
-(void) write:(NSData *)d
{
//send BLE packet
NSData *data = [NSData dataWithBytes: &d length: sizeof(d)];
NSLog(#"%#", data);
}
#end
ViewController.h
#import <UIKit/UIKit.h>
#import "BLE.h"
#interface ViewController : UIViewController<BLEDelegate>
#property (nonatomic, strong) BLE *ble;
#property (weak, nonatomic) IBOutlet UIButton *btnClicked;
#end
ViewController.m
#import "ViewController.h"
#import "SecondViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize ble;
- (void)viewDidLoad {
[super viewDidLoad];
ble = [[BLE alloc] init];
ble.delegate = self;
}
-(void)bleDidReceiveData:(unsigned char *)data length:(int)length
{
//parse data
}
- (IBAction)btnClicked:(id)sender
{
uint32_t packet = 0xFFFF;
NSData *data = [NSData dataWithBytes: &packet length: sizeof(packet)];
[ble write:data];
}
#end
SecondViewController.h
#import <UIKit/UIKit.h>
#import "BLE.h"
#interface SecondViewController : UIViewController<BLEDelegate>
#property (nonatomic, strong) BLE *ble;
#property (weak, nonatomic) IBOutlet UIButton *btnClicked;
#end
SecondViewController.m
#import "SecondViewController.h"
#import "ViewController.h"
#interface SecondViewController ()
#end
#implementation SecondViewController
#synthesize ble;
- (void)viewDidLoad {
[super viewDidLoad];
ble = [[BLE alloc] init];
ble.delegate = self;
}
-(void)bleDidReceiveData:(unsigned char *)data length:(int)length
{
//parse data
}
- (IBAction)btnClicked:(id)sender
{
uint32_t packet = 0xFFFF;
NSData *data = [NSData dataWithBytes: &packet length: sizeof(packet)];
[ble write:data];
}
#end

Related

objective C making UITextField for vc1 become UILabel vc2

I am trying to get my UITextField email in my first view controller to become the UILabel in my next view controller. It says there is an error stating there is no visible #interface for NSString declares the selector initvalue. I thought the interface was being loaded from the vc1.h file when you imported it on the vc2? any help would be nice. Heres what I have so far:
vc1.h
#import <UIKit/UIKit.h>
#interface loginUserViewController : UIViewController
#property (nonatomic, retain, strong) IBOutlet UITextField *email;
#property (nonatomic, retain) IBOutlet UITextField *password;
#property (nonatomic, retain) IBOutlet UIButton *login;
#property (nonatomic,retain) IBOutlet UIButton *registerBtn;
-(IBAction)loginUser:(id)sender;
#end
vc2.h
#import <UIKit/UIKit.h>
#import "loginUserViewController.h"
#interface Home : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *username;
#property (weak, nonatomic) IBOutlet UIBarButtonItem *Nav;
#property (weak, nonatomic) IBOutlet UIBarButtonItem *logout;
-(IBAction)logout:(id)sender;
-(IBAction)bandHome:(id)sender;
#end
vc2.m
import "Home.h"
#import "loginUserViewController.h"
#interface Home ()
#end
#implementation Home
#synthesize username, band1, band2, band3;
-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if(self){
}
return self;
}
-(void)viewDidLoad
{
[super viewDidLoad];
loginUserViewController *object = [[loginUserViewController alloc]init];
NSString *string = [[NSString alloc] initWithFormat:#"%i",[object.email.text initValue]];
username.text = string;
}
vc1.m
#import "loginUserViewController.h"
#import "Home.h"
#import "createBandViewController.h"
#interface loginUserViewController ()
#end
#implementation loginUserViewController
#synthesize email, password;
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
}
- (void)viewDidload
{
[super viewDidLoad];
}
- (void)viewDidUnload
{
[self setEmail:nil];
[self setPassword:nil];
[super viewDidUnload];
}
-(IBAction)loginUser:(id)sender {
if ([email.text isEqualToString:#""] || [password.text isEqualToString:#""])
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"alert" message:#"Please Fill all the field" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
return;
}
Simply replace this string:
NSString *string = [[NSString alloc] initWithFormat:#"%i",[object.email.text initValue]];
with this string:
NSString *string = [[NSString alloc] initWithFormat:#"%i",[object.email.text intValue]];
and if you want simply the email just as a string then replace it with this string
NSString *string = [[NSString alloc] initWithFormat:#"%#",object.email.text];
your error will be resolved.Hope it helps :)
First of All in VC2.h
#import <UIKit/UIKit.h>
#import "loginUserViewController.h"
#interface Home : UIViewController
#property (strong, nonatomic) IBOutlet UILabel *username; // Keep property strong to get the value
in VC2.m
#synthesize username;
Now in VC1.h
#import <UIKit/UIKit.h>
#import "homeviewcontroller.h"
#interface loginUserViewController : UIViewController
#property (nonatomic, strong) IBOutlet UITextField *email;
#property (nonatomic, strong) IBOutlet UITextField *password;
#property (nonatomic) nsstring *username;
-(void)viewDidLoad
{
[super viewDidLoad];
username= self.email.text;
homeviewcontroller *object = [[homeviewcontroller alloc]init];
object.username.text=username;
}

accessing IBOutlet properties from another class

How do I access IBOutlets that have been created in another class?
here is my code...
Class one
.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (retain, readwrite) IBOutlet UIView *myView;
#end
.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize myView;
- (void)viewDidLoad {
[super viewDidLoad];
}
#end
Class two
.h
#import <UIKit/UIKit.h>
#interface ViewController2 : UIViewController
- (IBAction)accion:(id)sender;
- (IBAction)btnBack:(id)sender;
#end
.m
#import "ViewController.h"
#import "ViewController2.h"
#interface ViewController2 ()
#end
#implementation ViewController2
- (void)viewDidLoad {
[super viewDidLoad];
}
- (IBAction)accion:(id)sender {
ViewController *a = [ViewController new];
UIView *someView = [a myView];
[someView setBackgroundColor:[UIColor redColor]];
}
- (IBAction)btnBack:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
#end
why not works? no change the backgroundColor when return on my view
I think you try to delegate pattern to set the values Viewcontroller2.h file
Add protocol like this...
#import <UIKit/UIKit.h>
#protocol tutorialDelegate <NSObject> //set protocol
-(void)delegatesDescribedWithDescription;
#end
#interface ViewController2 : UIViewController
#property (weak, nonatomic) id<tutorialDelegate> tutorialDelegate1;
- (IBAction)accion:(id)sender;
- (IBAction)btnBack:(id)sender;
#end
after the declaring protocol in viewcontroller2.m file first synthesize and call method like this..
#import "ViewController.h"
#interface ViewController2 ()
#end
#implementation ViewController2
#synthesize tutorialDelegate1; // synthesize here
- (void)viewDidLoad {
[super viewDidLoad];
}
- (IBAction)accion:(id)sender {
ViewController *a = [ViewController new];
UIView *someView = [a myView];
[someView setBackgroundColor:[UIColor redColor]];
}
- (IBAction)btnBack:(id)sender {
// Here we tell delegate to invoke method in parent view.
[self.tutorialDelegate1 delegatesDescribedWithDescription
];
[self dismissViewControllerAnimated:YES completion:nil];
}
#end
and finally we implement this method in view controller.m file but first set delegate in viewcotroller.h file like this...
#import <UIKit/UIKit.h>
#import "ViewController2.h" //import here
#interface ViewController : UIViewController <tutorialDelegate> //set delegate
#property (retain, readwrite) IBOutlet UIView *myView;
#end
and viewcontroller.m file
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize myView;
- (void)viewDidLoad {
[super viewDidLoad];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"yourIdentifier"]) {
ViewController2 *detailViewController =
segue.destinationViewController;
// here we set the ViewController to be delegate in
// detailViewController
detailViewController.tutorialDelegate1 = self;
}
}
// ViewController must implement tutorialDelegate's methods
// because we specified that ViewController will conform to
// tutorialDelegate protocol
-(void)delegatesDescribedWithDescription
{ // here your code please
viewTemp.backgroundColor =[UIColor redColor];
}
#end

My Delegate method is not getting Called

I just started learning objective-c, i was breaking my head why this below simple code for protocols and delegates is not working, please clarify me why this is delegate method is not getting called. Thanks in advance.
ViewController.h
#import <UIKit/UIKit.h>
#include "secondViewController.h"
#interface ViewController : UIViewController<ConverterDelegate>
#property (strong,nonatomic) secondViewController *secondview;
#property (strong, nonatomic) IBOutlet UILabel *msgtext;
#property (strong, nonatomic) IBOutlet UIButton *converbutton;
#end
ViewController.m
#import "ViewController.h"
#import "secondViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize msgtext,converbutton,secondview;
- (void)viewDidLoad
{
[super viewDidLoad];
self.secondview=[[secondViewController alloc]init];
secondview.delegate=self;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)convertToFahrenheit:(int)celsius{
float fah = ((1.8)*celsius)+32;
msgtext.text = [NSString stringWithFormat:#"the %i deg Celsius equal to %.2f Fah",celsius,fah];
}
#end
SecondViewController.h
#import <UIKit/UIKit.h>
#protocol ConverterDelegate <NSObject>
#required
-(void)convertToFahrenheit:(int)celsius;
#end
#interface secondViewController : UIViewController
#property (nonatomic, assign) id <ConverterDelegate> delegate;
#property (strong, nonatomic) IBOutlet UITextField *textfield;
- (IBAction)convert:(id)sender;
#end
secondViewController.m
#import "secondViewController.h"
#interface secondViewController ()
#end
#implementation secondViewController
#synthesize textfield,delegate;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (IBAction)convert:(id)sender {
[delegate convertToFahrenheit:[textfield.text intValue]];
//[self dismissViewControllerAnimated:YES completion:nil];
}
#end
I was totally confused why my delegate method is not getting called. I a newbie to Objective c please help me.
I hope following code will fulfil your requirements.
ViewController.h
#import <UIKit/UIKit.h>
#import "Calculation.h"
#interface ViewController : UIViewController<CalculationDelegate>
#property (weak, nonatomic) IBOutlet UILabel *msgtext;
#property (weak,nonatomic) IBOutlet UITextField * inputField;
#property (weak, nonatomic) IBOutlet UIButton *converbutton;
-(IBAction)convertMetod:(id)sender;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize msgtext,converbutton,inputField;
- (void)viewDidLoad
{
[super viewDidLoad];
}
-(IBAction)convertMetod:(id)sender
{
Calculation * CalculationObj = [[Calculation alloc] init];
CalculationObj.delegate = self;
[CalculationObj convertCelToFaher:[inputField.text intValue]];
}
-(void)showTheAns:(NSString *)ans
{
NSLog(#"delegate method called");
msgtext.text = ans;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Calculation.h
#import <Foundation/Foundation.h>
#protocol CalculationDelegate <NSObject>
#required
-(void) showTheAns:(NSString *) ans;
#end
#interface Calculation : NSObject
#property (strong,nonatomic) id <CalculationDelegate> delegate;
-(void)convertCelToFaher:(int)celsius;
#end
Calculation.m
#import "Calculation.h"
#implementation Calculation
#synthesize delegate;
-(void)convertCelToFaher:(int)celsius
{
float fah = ((1.8)*celsius)+32;
[delegate showTheAns:[NSString stringWithFormat:#"the %i deg Celsius equal to %.2f Fah",celsius,fah]];
}
#end

Cannot set the value of a NSString from another class

I've searched all over google, and stack overflow for a solution, but I wasn't able to find an answer that solved my problem. Sorry for the long post, as I'm trying to give as much information as I can. I'm new to iOS and Objective- c, but not programming in general due to being asked to switch over from Android by my company, so any help is appreciated.
I'm trying to assign a value to an NSString in one class from a TextField in another, but I get the error:
**-[ViewController name:]: unrecognized selector sent to instance 0x78712fe0**
when I run the app in the simulator.
Relevant code:
//UserInfo.h
#import <Foundation/Foundation.h>
#interface UserInfo : NSObject <NSCoding>
#property (nonatomic, strong) NSString *name;
#property (nonatomic, strong) NSString *age;
#property (nonatomic, strong) NSString *address;
#end
//UserInfo.m
#import "UserInfo.h"
static NSString *nameKey = #"userName";
static NSString *ageKey = #"userAge";
static NSString *addressKey = #"userAddress";
static NSString *userInfoKey = #"userInfoKey";
#implementation UserInfo
#synthesize name;
#synthesize age;
#synthesize address;
- (id) initWithCoder:(NSCoder *)coder
{
self = [super init];
self.name = [coder decodeObjectForKey:nameKey];
self.age = [coder decodeObjectForKey:ageKey];
self.address = [coder decodeObjectForKey:addressKey];
return self;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[coder encodeObject:self.name forKey:nameKey];
[coder encodeObject:self.age forKey:ageKey];
[coder encodeObject:self.address forKey:addressKey];
}
#end
//ViewController.h
#import <UIKit/UIKit.h>
#import "UserInfo.h"
#interface ViewController : UIViewController <UITextFieldDelegate, UITextViewDelegate, NSCoding>
#property (nonatomic, strong) UserInfo *userInfoObject;
#property (nonatomic, weak) IBOutlet UILabel *titleLabel;
#property (nonatomic, weak) IBOutlet UILabel *nameLabel;
#property (nonatomic, weak) IBOutlet UILabel *ageLabel;
#property (nonatomic, weak) IBOutlet UILabel *addressLabel;
#property (nonatomic, weak) IBOutlet UITextField *nameText;
#property (nonatomic, weak) IBOutlet UITextField *ageText;
#property (nonatomic, weak) IBOutlet UITextField *addressText;
#property (nonatomic, weak) IBOutlet UIButton *saveBtn;
- (IBAction)saveBtnTouched:(id)sender;
- (void) saveUserInfo;
- (void) loadUserInfo;
- (void) setUserInterfaceValues;
- (IBAction)nameText:(id)sender;
- (IBAction)ageText:(id)sender;
- (IBAction)addressText:(id)sender;
#end
//ViewController.m
#import "ViewController.h"
#import "UserInfo.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize titleLabel;
#synthesize nameLabel;
#synthesize ageLabel;
#synthesize addressLabel;
#synthesize nameText;
#synthesize ageText;
#synthesize addressText;
#synthesize saveBtn;
static NSString *userInfoKey = #"userInfoKey";
- (void)viewDidLoad {
[super viewDidLoad];
[self loadUserInfo];
if(!self.userInfoObject)
{
self.userInfoObject = [[UserInfo alloc] init];
}
[self setUserInterfaceValues];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
self.saveBtn.enabled = YES;
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField*)textField
{
return YES;
}
- (BOOL) textFieldShouldEndEditing:(UITextField *)textField
{
[self.nameText resignFirstResponder];
[self.ageText resignFirstResponder];
[self.addressText resignFirstResponder];
return YES;
}
- (IBAction)saveBtnTouched:(id)sender
{
NSLog(#"%# was entered into the name field", self.nameText.text);
NSLog(#"%# was entered into the age field", self.ageText.text);
NSLog(#"%# was entered into the address field", self.addressText.text);
[self textFieldShouldEndEditing:self.nameText];
[self textFieldShouldEndEditing:self.ageText];
[self textFieldShouldEndEditing:self.addressText];
self.userInfoObject.name = self.nameText.text;
self.userInfoObject.age = self.ageText.text;
self.userInfoObject.address = self.addressText.text;
[self saveUserInfo];
self.saveBtn.enabled = NO;
}
- (void)saveUserInfo
{
NSData *userInfoData = [NSKeyedArchiver archivedDataWithRootObject:self.userInfoObject];
[[NSUserDefaults standardUserDefaults] setObject:userInfoData forKey:userInfoKey];
}
- (void)loadUserInfo
{
NSData *userInfoData = [[NSUserDefaults standardUserDefaults] objectForKey:userInfoKey];
if(userInfoData)
{
self.userInfoObject = [NSKeyedUnarchiver unarchiveObjectWithData:userInfoData];
}
}
- (void) setUserInterfaceValues
{
self.nameText.text = self.userInfoObject.name;
self.ageText.text = self.userInfoObject.age;
self.addressText.text = self.userInfoObject.address;
}
- (IBAction)nameText:(id)sender {
}
- (IBAction)ageText:(id)sender {
}
- (IBAction)addressText:(id)sender {
}
#end
//AppDelegate.h
#import <UIKit/UIKit.h>
#import "ViewController.h"
#import "UserInfo.h"
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) ViewController *viewController;
#end
//AppDelegate.m
#import "AppDelegate.h"
#import "ViewController.h"
#import "UserInfo.h"
#interface AppDelegate ()
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
//all the other generated methods. Taken out due to space.
#end
Three breakpoints are set that are supposidly the source of the problem:
From the ViewController.m, in - (void)setUserInterfaceValues
self.nameText.text = self.userInfoObject.name;
(I assume that this applies to the other two lines below it also)
Also from the ViewController.m, in - (void)viewDidLoad
[self setUserInterfaceValues];
And finally from the AppDelegate.m, in - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
self.window.rootViewController = self.viewController;
From what I understand, and have learned from searching this issue, the app is trying to send data to something that doesn't exist, the NSString name being the culprit. Others have suggested to make sure that my .xib file is connected to the ViewController, and I have verified that it is.
As another bit of information, I'm not using a storyboard for this app, and instead am using the interface builder. I'm aware that there are advantages to storyboards, and I would like to be using them, but my company uses the interface builder and does a lot of things programmatically, so I'm learning to develop without.
[EDIT]: Issue solved thanks to Ian.

Cannot find protocol declaration for changeMapTyp iOS

I currently get the error "cannot find protocol declaration for changeMapTyp" and I have no idea why. I imported all the required files, but it hasn't solved my problem.
As mentioned in my comments, the error message disappears when I delete the #import MapsViewController.h in the MapsBackgroundViewController.h, but I can´t delete the line, because I need to write this lines
MapsViewController *myMapsViewController = [[MapsViewController alloc] init];
[self setDelegate:myMapsViewController];
to set my delegate. Am I right?
Here is my code:
MapsBackgroundViewcontroller.h
#import "MapsViewController.h"
#protocol ChangeMapTyp <NSObject>
#required
- (void)segmentedControllChangedMapType:(MKMapType) type ;
#end
#interface MapBackgroundViewController : UIViewController{
IBOutlet UISegmentedControl *segmentedControl;
MKMapType mapType;
id < ChangeMapTyp> delegate;
}
#property (nonatomic) IBOutlet UISegmentedControl *segmentedControl;
#property(nonatomic) MKMapType mapType;
#property(nonatomic)id delegate;
- (IBAction)segmentedControllChanged:(id)sender;
MapsBackgroundViewController.m
#import "MapBackgroundViewController.h"
#interface MapBackgroundViewController ()
#end
#implementation MapBackgroundViewController
#synthesize segmentedControl, mapType, delegate;
- (void)viewDidLoad
{
[super viewDidLoad];
// that´s why I can´t delete the import ???
MapsViewController *myMapsViewController = [[MapsViewController alloc] init];
[self setDelegate:myMapsViewController];
}
- (IBAction)segmentedControllChanged:(id)sender {
if (segmentedControl.selectedSegmentIndex == 0) {
mapType = MKMapTypeStandard;
}else if (segmentedControl.selectedSegmentIndex == 1) {
mapType = MKMapTypeSatellite;
} else if (segmentedControl.selectedSegmentIndex == 2) {
// [self.delegate setMapType:MKMapTypeHybrid];
mapType = MKMapTypeHybrid;
}
//Is anyone listening
if([delegate respondsToSelector:#selector(segmentedControllChangedMapType:)])
{
//send the delegate function with the amount entered by the user
[delegate segmentedControllChangedMapType:mapType];
}
[self dismissModalViewControllerAnimated:YES];
}
MapsViewController.h
#import "MapBackgroundViewController.h"
#class MapBackgroundViewController;
#interface MapsViewController : UIViewController<MKMapViewDelegate,
UISearchBarDelegate, ChangeMapTyp >{ //here i get the error message
#private
IBOutlet MKMapView *map;
}
#property (nonatomic, retain) IBOutlet MKMapView *map;
#end
MapsViewController.m
#import "MapBackgroundViewController.h"
#interface MapsViewController ()
#end
#implementation MapsViewController
#synthesize map;
- (void)segmentedControllChangedMapType: (MKMapType) type{
map.mapType = type;
}
In MapsViewController.h, you need to have -
#import "MapBackgroundViewController.h" //Keep This line
#class MapBackgroundViewController; // Remove this line
#interface MapsViewController : UIViewController<MKMapViewDelegate,UISearchBarDelegate, ChangeMapTyp >{
Hope this will fix your issue.

Resources