Reputation: 13
I have a project in Swift in which I added a ViewController written in Objective C that ranges all beacons that it finds in his range (didn't find a swift code for this - this is why I'm using Obj C). I connected the two ViewControllers and all is good, the beacons are displayed on the screen of the Objective C ViewController. The problem is that I need to access, from the Objective C ViewController, a dictionary ("beaconsDict"), that is created in there, so I can pass all beacons RSSIs to a BLE gateway afterwards. The problem is that I don't know how to read/access from the Swift ViewController the Dictionary from the Obj C ViewController so I can create a list of RSSIs which, afterwards, I will pass to the BLE Gateway.
(the bridging is done and as I mentioned the Obj C ViewController is visible in my application, at a push of a button, and works as expected)
Obj C ViewController m file:
#import "AIBMainTableViewController.h"
#import "AIBBeaconRegionAny.h"
#import "AIBUtils.h"
#import "AIBDetailViewController.h"
#define kCellIdentifier @"cellBeaconIdentifier"
@import CoreLocation;
@interface AIBMainTableViewController ()<CLLocationManagerDelegate>
@property(nonatomic, strong) NSDictionary* beaconsDict;
@property(nonatomic, strong) CLLocationManager* locationManager;
@property(nonatomic, strong) NSArray* listUUID;
@property(nonatomic) BOOL sortByMajorMinor;
@property(nonatomic, retain) CLBeacon* selectedBeacon;
@end
@implementation AIBMainTableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.clearsSelectionOnViewWillAppear = NO;
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.listUUID=[[NSArray alloc] init];
self.beaconsDict=[[NSMutableDictionary alloc] init];
self.sortByMajorMinor=NO;
AIBBeaconRegionAny *beaconRegionAny = [[AIBBeaconRegionAny alloc] initWithIdentifier:@"Any"];
[self.locationManager requestWhenInUseAuthorization];
[self.locationManager startRangingBeaconsInRegion:beaconRegionAny];
self.navigationItem.rightBarButtonItem=[[UIBarButtonItem alloc] initWithTitle:@"Order by major/minor" style:UIBarButtonItemStylePlain target:self action:@selector(changeOrdenation)];
}
- (void) changeOrdenation{
_sortByMajorMinor=!_sortByMajorMinor;
if (_sortByMajorMinor){
self.navigationItem.rightBarButtonItem.title=@"Order by distance";
} else {
self.navigationItem.rightBarButtonItem.title=@"Order by major/minor";
}
}
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
NSLog(@"locationManagerDidChangeAuthorizationStatus: %d", status);
[UIAlertController alertControllerWithTitle:@"Authoritzation Status changed"
message:[[NSString alloc] initWithFormat:@"Location Manager did change authorization status to: %d", status]
preferredStyle:UIAlertControllerStyleAlert];
}
- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region
{
NSLog(@"locationManager:%@ didRangeBeacons:%@ inRegion:%@",manager, beacons, region);
NSMutableArray* listUuid=[[NSMutableArray alloc] init];
NSMutableDictionary* beaconsDict=[[NSMutableDictionary alloc] init];
for (CLBeacon* beacon in beacons) {
NSLog(@"rssi is : %ld", beacon.rssi);
NSString* uuid=[beacon.proximityUUID UUIDString];
NSMutableArray* list=[beaconsDict objectForKey:uuid];
if (list==nil){
list=[[NSMutableArray alloc] init];
[listUuid addObject:uuid];
[beaconsDict setObject:list forKey:uuid];
}
[list addObject:beacon];
}
[listUuid sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
NSString* string1=obj1;
NSString* string2=obj2;
return [string1 compare:string2];
}];
if (_sortByMajorMinor){
for (NSString* uuid in listUuid){
NSMutableArray* list=[beaconsDict objectForKey:uuid];
[list sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
CLBeacon* b1=obj1;
CLBeacon* b2=obj2;
NSComparisonResult r=[b1.major compare:b2.major];
if (r==NSOrderedSame){
r=[b1.minor compare:b2.minor];
}
return r;
}];
}
}
_listUUID=listUuid;
_beaconsDict=beaconsDict;
[self.tableView reloadData];
}
- (void)locationManager:(CLLocationManager *)manager rangingBeaconsDidFailForRegion:(CLBeaconRegion *)region withError:(NSError *)error
{
NSLog(@"locationManager:%@ rangingBeaconsDidFailForRegion:%@ withError:%@", manager, region, error);
[UIAlertController alertControllerWithTitle:@"Ranging Beacons fail"
message:[[NSString alloc] initWithFormat:@"Ranging beacons fail with error: %@", error]
preferredStyle:UIAlertControllerStyleAlert];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [_listUUID count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
NSString* key=[_listUUID objectAtIndex:section];
return [[_beaconsDict objectForKey:key] count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
return [_listUUID objectAtIndex:section];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier forIndexPath:indexPath];
NSString* key=[_listUUID objectAtIndex:[indexPath indexAtPosition:0]];
CLBeacon* beacon=[[_beaconsDict objectForKey:key] objectAtIndex:[indexPath indexAtPosition:1]];
cell.textLabel.text=[[NSString alloc] initWithFormat:@"RSSI:%ld", (long)beacon.rssi];
cell.detailTextLabel.text=[[NSString alloc] initWithFormat:@"Distance: %.2fm\tProximity: %@", beacon.accuracy, [AIBUtils stringForProximityValue:beacon.proximity]];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSString* key=[_listUUID objectAtIndex:[indexPath indexAtPosition:0]];
_selectedBeacon=[[_beaconsDict objectForKey:key] objectAtIndex:[indexPath indexAtPosition:1]];
AIBDetailViewController* detail=[self.storyboard instantiateViewControllerWithIdentifier:@"detail"];
detail.beacon=_selectedBeacon;
[self.navigationController pushViewController:detail animated:YES];
}
@end
Obj C ViewController h file:
#import <UIKit/UIKit.h>
@interface AIBMainTableViewController : UITableViewController
@end
Upvotes: 0
Views: 243
Reputation: 2294
Approach 1:
Declare NSDictionary *dictionaryBeacons;
in your .h file.
Initialization and value assignment will happen in .m
Then in .swift file you can declare one property like var dictBeacons: [String:Any]?
Now in .m file you can create object of swift view controller and pass dict as parameter like
vcObject.dictBeacons = dictionaryBeacons;
and then PUSH it using navigation controller.
Approach 2:
If you don't want PUSH controller and use it in random .swift class then
Declare @property(nonatomic, strong) NSDictionary *dictionaryBeacons;
in your .h file and use it any .swift class by creating object of VC like vcObject.dictionaryBeacons
Upvotes: 0