0

I am trying to set up a UIButton to control a GPIO pin on a Raspberry PI via IOS app.

I am having an issue with UIButton and getting a few erros "Use of undeclared identifier 'self" as well as "expected identifier or '(" and an error "Initializer element is not a compile-time Constant." The Code I have is below

   //

#import "ViewController.h"


@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self initNetworkCommunication];

    //used so that when you minimize the app it inits the the network again.
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(applicationEnteredForeground:)
                                                 name:UIApplicationWillEnterForegroundNotification
                                               object:nil];


    _logo.layer.cornerRadius = _logo.frame.size.width / 2;
    _logo.clipsToBounds = YES;
    _logo.layer.borderColor = [[UIColor whiteColor] CGColor];
    _logo.layer.borderWidth = 6;

    self.view.backgroundColor = [UIColor colorWithRed:(2/255.0f) green:(160/255.0f) blue:(224/255.0f) alpha:1];
}

- (void)applicationEnteredForeground:(NSNotification *)notification {
    [self initNetworkCommunication];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
- (void)initNetworkCommunication {
    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;
    CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"192.168.1.50", 7777, &readStream, &writeStream);
    _inputStream = (NSInputStream *)CFBridgingRelease(readStream);
    _outputStream = (NSOutputStream *)CFBridgingRelease(writeStream);

    [_inputStream setDelegate:self];
    [_outputStream setDelegate:self];

    [_inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [_outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

    [_inputStream open];
    [_outputStream open];

}


- (IBAction)toggleValve:(id)sender {

    UISegmentedControl*button = ((UISegmentedControl*)sender);
    long tag = button.tag;

    NSString *response  = [NSString stringWithFormat:@"P%ld%@", tag , button.selectedSegmentIndex?@"L" : @"H"];
    NSData *data = [[NSData alloc] initWithData:[response dataUsingEncoding:NSASCIIStringEncoding]];
    [_outputStream write:[data bytes] maxLength:[data length]];

}

UIButton *valveToggle = [UIButton buttonWithType:UIButtonTypeRoundedRect];

[valveToggle addTarget:self  action:@selector(holdDown)forControlEvents:UIControlEventTouchDown];

[valveToggle addTarget:self action:@selector(holdRelease) forControlEvents: UIControlEventTouchUpInside];

-(void) holdDown{
    NSLog(@"hold Down");
    //Set GPIO High
}
-(void)holdRelease {
    NSLog(@"hold release");
    //Set GPIO Low
}


- (IBAction)shutdown:(id)sender {

    NSData *data = [[NSData alloc] initWithData:[@"shutdown" dataUsingEncoding:NSASCIIStringEncoding]];
    [_outputStream write:[data bytes] maxLength:[data length]];

}

- (IBAction)reboot:(id)sender {

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"REBOOT?" message:@"Are you sure you want to reboot?" delegate:self cancelButtonTitle:@"OH.. Hell No!" otherButtonTitles:@"I said REBOOT!", nil];

    [alert show];

}

- (void)alertView:(UIAlertController *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{

    if(buttonIndex == 1){

        NSData *data = [[NSData alloc] initWithData:[@"reboot" dataUsingEncoding:NSASCIIStringEncoding]];
        [_outputStream write:[data bytes] maxLength:[data length]];
        NSLog(@"YES %@",data);
    }
}

- (IBAction)reset:(id)sender {
    [self initNetworkCommunication];
}
 @end

Here is a picture of the Error codes

screen shot of Error codes

The code block is 
UIButton *valveToggle = [UIButton buttonWithType:UIButtonTypeRoundedRect];

[[valveToggle addTarget:self  action:@selector(holdDown)forControlEvents:UIControlEventTouchDown];

[[valveToggle addTarget:self action:@selector(holdRelease) forControlEvents: UIControlEventTouchUpInside];

-(void) holdDown{
    NSLog(@"hold Down");
    //Set GPIO High
}
-(void)holdRelease {
    NSLog(@"hold release");
    //Set GPIO Low
}

Below is my Header file.

// //  ViewController.h //  RocketOne // //  Created by Christopher      Beck
on 8/9/2559 BE. //  Copyright © 2559 BE Christopher Beck. All rights              reserved. //

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController<NSStreamDelegate> {
}

@property (nonatomic, retain) NSInputStream *inputStream;
@property  (nonatomic, retain) NSOutputStream *outputStream;
@property (weak,nonatomic) IBOutlet UIButton *valveToggle;
@property (weak, nonatomic)IBOutlet UIImageView *logo;

- (IBAction)ToggleValve:(id)sender;
- (IBAction)shutdown:(id)sender;
- (IBAction)reboot:(id)sender;
- (IBAction)reset:(id)sender;



@end

Any help in resolving this error would be greatly appreciated! I am new to this and guessing it is something simple.

Chris B
  • 1
  • 3
  • Why is `UIControlEventTouchUpInside ` on it's own on a line (it looks like it should be inside the `addTarget: forControlEvents:` on the previous line)? Why does `- (void) holdDown` not have a closing brace? Why does `- (void)holdRelease` not have a closing brace? You should probably use a Storyboard so that you don't make mistakes when coding your UI. – Robotic Cat Aug 15 '16 at 15:01
  • You are correct the UIControlEventTouchUpInside should be on the previous line. My mistake. Again when I moved the code over the closing brackets got moved up a line. Sorry for the confusion. – Chris B Aug 15 '16 at 19:12
  • As it stands I do not understand the code you have posted. All 3 statements for `valveToggle` should be in a code block for a method. Please post your full methods around the error. – Robotic Cat Aug 15 '16 at 21:06
  • I updated the question with all the code. It seems now I am getting an error for "Use of undeclared identifier 'self" as well as "expected identifier or '(" and an error "Initializer element is not a compile-time Constant." I was following this tutorial http://bitcows.com/?p=249 and trying to change it from a segment control button to a Unbutton that acted like a momentary switch but I can't seem to figure it out. Thank you for your help! – Chris B Aug 16 '16 at 02:39

2 Answers2

0

The problem is as I described in the comments. You have three lines of code sitting on their own in your ViewController.m file that should be within a method. These lines cannot be on their own:

UIButton *valveToggle = [UIButton buttonWithType:UIButtonTypeRoundedRect];

[valveToggle addTarget:self  action:@selector(holdDown)forControlEvents:UIControlEventTouchDown];

[valveToggle addTarget:self action:@selector(holdRelease) forControlEvents: UIControlEventTouchUpInside];

It looks like you were trying to create part of your UI with these lines; my recommendation is you just use a Storyboard rather than using code. If you want to continue with these lines then stick them inside viewDidLoad (but see this SO post for more information: Which should I use, -awakeFromNib or -viewDidLoad?) and add the button to the UI.

For example:

- (void)viewDidLoad:(BOOL)animated {
    [super viewDidLoad];

    // Now your code is inside a method
    UIButton *valveToggle = [UIButton buttonWithType:UIButtonTypeRoundedRect];

    [valveToggle addTarget:self  action:@selector(holdDown)forControlEvents:UIControlEventTouchDown];

    [valveToggle addTarget:self action:@selector(holdRelease) forControlEvents: UIControlEventTouchUpInside];

    // You are missing a button title, a frame and adding the button to the UI - you should use a Storyboard instead
    [valveToggle setTitle:@"Toggle Valve" forState:UIControlStateNormal];
    button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0); // Example size - set correctly but prefer constraints
    [self.view addSubview:valveToggle];
}
Community
  • 1
  • 1
Robotic Cat
  • 5,899
  • 4
  • 41
  • 58
  • That makes sense. Let me try that tonight and see where I get. Thanks for the patience and help! – Chris B Aug 16 '16 at 14:26
-1

There are some code blunts i believe not helping your cause ...

// Improved code are given below,  
UIButton *valveToggle = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 

[valveToggle addTarget:self  action:@selector(holdDown)forControlEvents:UIControlEventTouchDown];

[valveToggle addTarget:self action:@selector(holdRelease) forControlEvents: UIControlEventTouchUpInside];

-(void) holdDown{
        NSLog(@"hold Down");
       //Set GPIO High 
}
-(void)holdRelease {
    NSLog(@"hold release");
    //Set GPIO Low 
}

P.S i believe you question is not clear.

  • Sorry if my questions is confusing. I am confused by why I am getting a "Use of Undeclared Identifier 'holdDown" Error for the line with "-(void) holdDown{" Is this because I did not declare something in my .h file? – Chris B Aug 15 '16 at 19:17
  • you don't need to declare function in Header (.h) file until unless you want to access that from other controller.Do some nessarcy step. 1. clean the code. 2. If possible restart Xcode, even Mac. 3. Try again. if you are Ok with method definition then i believe there will be no issue. Please make sure your function define perfectly. i.e. -(void)holdDown{} – M Abubaker Majeed Aug 16 '16 at 09:16
  • How would I define -(void)holdDown{}? Do I put -(void)holdDown{} in my .h file and then define what it is with in the {}? I thought "holdDown" was a function from a UIButton library? doesn't this code define what the function is? [_valveToggle addTarget:self action:@selector(holdDown)forControlEvents:UIControlEventTouchDown]; I am pretty lost as you can see! any examples of how this is done would be greatly appreciated! – Chris B Aug 17 '16 at 22:51
  • Alright I think I get it, but I am still getting "Use of undeclared identifier hold down" when I am trying to define the function? Should I be defining it somewhere else? – Chris B Aug 18 '16 at 01:22