Can anyone tell me where I'm going wrong here please. I have created an NSobject called BeaconData. The header file is:
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#import <CoreBluetooth/CoreBluetooth.h>
@interface BeaconData : NSObject
@property (nonatomic, strong) NSMutableArray * jsonArray;
@property (nonatomic, retain) NSString * bMajor;
@property (nonatomic, retain) NSString * bMinor;
@property (nonatomic, retain) NSString * bUUID;
-(void) getData;
@end
The implementation file is then:
#import "BeaconData.h"
#define getDataURL @"http://www.eventav.biz/websitebeacons/library/json/files/beacons.txt"
@implementation BeaconData
@synthesize jsonArray, bUUID, bMajor, bMinor;
//Retrieve data
-(void) getData
{
extern NSString * bUUID;
extern NSString * bMajor;
extern NSString * bMinor;
NSURL * url = [NSURL URLWithString:getDataURL];
NSData * data = [NSData dataWithContentsOfURL:url];
jsonArray = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
//Loop through Json Array
for (int i = 0; i < jsonArray.count; i++)
{
bUUID = [[jsonArray objectAtIndex:i] objectForKey:@"i_uuid"];
bMajor = [[jsonArray objectAtIndex:i] objectForKey:@"i_major"];
bMinor = [[jsonArray objectAtIndex:i] objectForKey:@"i_minor"];
}
}
@end
Next I try to call the Global variable bMajor in the main viewController.m file and print it out - just to see if it works, like this:
- (void)viewDidLoad {
[super viewDidLoad];
extern NSString * bMajor;
NSInteger beaconMajorInt = [bMajor integerValue];
NSLog (@"Beacon bMajor is %li", (long)beaconMajorInt);
But all I get is the following error:
Undefined symbols for architecture x86_64: "_bMajor", referenced from: -[ViewController viewDidLoad] in ViewController.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)
You have declared your bMajor
variable as a class property. This means that you must instantiate an instance of your BeaconData
class to access the variable unless you include a class method.
However, in your code I see that you also want to make these variables global. It is redundant to declare a variable as a class property and then try to make it global. In objective-c simply declaring a variable outside the implementation section will make it global for all modules that import the file with the declaration. You do it like this:
NSString *bMajor = @"Your String";
@implementation BeaconData
// YOUR CLASS CODE
@end
You're using the extern
keyword incorrectly. It should be used in .h class files to let anything that imports it know that they have access to this variable. You also must declare it like I showed in the .m class file
.h looks like this:
extern NSString *bMajor;
@interface BeaconData : NSObject
@end
Just because you can do this doesn't mean you should. Based on your code I would suspect what you want to do is turn your -getData
instance method into a class method for a singleton that allows the class to manage these "global" variables while keeping with good coding practice.
This SO Q/A should provide you exactly what you need to create your singleton. I recommend you do it this way.
Then in your viewController you would access these variables by getting an instance of your class using the class method.