How to delete discovered bluetooth devices on ios 7? - objective-c

I use BeeTee project for discover nearby bluetooth devices. Everything is good, but if it discovered a device its store this somewhere, and i cant find it again. If the device doesnt send bluetooth signal the bluetooth manager write this in log: BTM: lost device "device_name" device_address
How can i delete discovered devices?

They are stored in a dictionary:
#property (retain, nonatomic) NSMutableDictionary *currentAvailableDevices;
If you want to delete one of them, you can call the the delegate method
- (void)removeBluetoothDevice:(BluetoothDevice *)bluetoothDevice
{
[self.currentAvailableDevices removeObjectForKey:bluetoothDevice.address];
[self.tableView reloadData];
}
But are you sure that this approach makes sense?

Related

Xcode project works in Simulator, not on device

Still working on my flash card-themed app. Completely baffled. Lots of possibly salient info.
I have a version which works flawlessly, both in simulator and on multiple devices. But, I made a mistake when submitting to the App Store (wrong Bundle ID and Name), so I created a new project and copied and pasted the code and storyboard. (I didn't just move the files; I recreated them and copied the code.)
First problem was that it wouldn't build because "duplicate symbol _answers in" RootViewController.o and DescendantViewController.o. And there were 3 such duplicate symbols.
Yes, I have declared NSMutableArray *answers in the implementation of both my RootVC and DescedantVC, so I concede that's suspect, except.... it's the exact same code as in the version that works.
Nevertheless, I saw an opportunity to clean up my code, so I created a #property (weak, nonatomic) NSMutableArray *answers in my RootVC and changed the code in the root and descendant View Controllers to reference self.answers. It compiles without any problems.
It runs in the simulator perfectly. As I've just copied the entire code base to a new project, I test everything - no problems. I'm very excited, so I do all the steps to submit to the App Store, except the last one "Submit for Review."
I want to show off to my friend, so I attach my iPhone 6, compile it, run it and when I select "Play" - crash!
The following line is the culprit.
answers = [self pickWrongAnswersIgnoringCard:questionCard];
Both in the simulator and on the device, the last line of the this method is:
return wrongAnswers;
In both cases, wrongAnswers is an array with 3 items.
In the simulator, answers also has 3 items. On my iPhone, answers is nil.
Does anyone have any idea what this could be? The only thing I can think of is that I created the project that works over a year ago and the one that fails today, so maybe some of the Apple settings in the two projects are different? Otherwise, I'm stumped.
Edit
The function, as requested:
-(NSMutableArray *)pickWrongAnswersIgnoringCard:(FlashCard *)questionCard {
NSMutableArray *wrongAnswers = [[NSMutableArray alloc] init];
FlashCard *randomCard;
for (int i=1; i<4; i++) {
do {
randomCard = [self pickARandomCardFromDeck:wrongAnswersSource];
} while ([randomCard.name isEqualToString:questionCard.name] || [wrongAnswers containsObject:randomCard]);
[wrongAnswers addObject:randomCard];
}
return wrongAnswers; // device or simulator, wrongAnswers.count = 3
}
I figured it out, even if I don't fully understand.
I changed from #property (weak, nonatomic) to #property (strong, nonatomic).
That solved it for me.
Works on both simulator and device now.

iOS9 startMonitoringSignificantLocationChanges doesn't launch app when terminated?

I'm working on an iPhone app that needs to send the current location to a server so it knows what push notifications to send. It doesn't have to be very precise, startMonitoringSignificantLocationChanges is perfect for my needs.
This all works well as long as the app is running on screen or in the background. However if I kill/terminate the app it doesn't work anymore. From what I understand the app should be automatically relaunched with the special UIApplicationLaunchOptionsLocationKey as launch option. However the app doesn't relaunch (at least not in simulator).
I've read some stuff here too:
Behaviour for significant change location API when terminated/suspended?
Does the automatic relaunching only work when the app is terminated from suspended state by the system and not when you manually kill the app? I also tried the special info.plist UIApplicationExitsOnSuspend which also terminates the app when it goes into the background. It doesn't get relaunched then either.
Is there a way to simulate the app being terminated by the system in the simulator?
What happens after an iOS update when the phone has restarted? Is there a way to make sure that the app will get relaunched?
An app is relaunched by an SLC regardless of how it was killed provided when it was killed at least one CLLocationManager had called startMonitoringSignificantLocationChanges. There is one caveat to this - in version iOS7.0(.x) it was broken. It started working again in iOS7.1+.
To get this working requires that you complete a few steps.
In you project capabilities you must enable the background mode location updates because you want to be woken in the background.
You need to add the key NSLocationAlwaysUsageDescription to the info.plist containing a description of why you want to always be able to use location in the background.
In the code you must request authorization from the user to always use location
In the code you must request that location updates continue to be delivered while in the background
In the code you must start monitoring for significant location changes
Here is an example:
AppDelegate,h
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#interface AppDelegate : UIResponder <UIApplicationDelegate, CLLocationManagerDelegate>
#property (strong, nonatomic) UIWindow *window;
#property CLLocationManager* locationMgr;
#end
AppDelegate.m
#import "AppDelegate.h"
#implementation AppDelegate
#synthesize locationMgr;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSLog(#"app launching");
locationMgr = [[CLLocationManager alloc] init];
[locationMgr setDelegate:self];
// Added in iOS8
if([locationMgr respondsToSelector:#selector(requestAlwaysAuthorization)])
[locationMgr requestAlwaysAuthorization];
// Added in iOS9
if([locationMgr respondsToSelector:#selector(setAllowsBackgroundLocationUpdates:)])
[locationMgr setAllowsBackgroundLocationUpdates:YES];
[locationMgr startMonitoringSignificantLocationChanges];
return YES;
}
-(void) locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
NSLog(#"app delegate received significant location change");
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:[[UIApplication sharedApplication] applicationIconBadgeNumber]+1];
}
#end
The first time you run the app on your device, click on OK to allow the app to use your location in the background when it is requested. Then double click the home button and swipe the app off the task switcher to kill it. Click home, then swipe up from the bottom of the screen to open the Control Center and turn on Airplane Mode, wait a few seconds, then turn off airplane mode. Watch the badge counter increment on your app.
It was launched by iOS on an SLC.
One gotcha I would like to add. If you create two CLLocationManager instances and call startMonitoringSignificantLocationChanges on both, then call stopMonitoringSignificantLocationChanges on one. Even though the other CLLocationManager will continue to receive SLC events while the app continues to run, when you app exits for any reason, it will not be relaunched.
It seems the last call before exit sets the relaunch behaviour.
start, start, stop, exit - app doesn't relaunch on SLC.
start, start, stop start, exit - app does relaunch on SLC.
I've answered a question like this.
You can check my answer on the link below.
https://stackoverflow.com/a/35722254/3368791.

EAAcessory errors while closing session with iOS 6.0 GM

There is a MFI device that is connected to iPhone 4S (6.0 GM) or to iPad (6.0 GM) via Bluetooth (2.1 + EDR). The project was built on Xcode 4.5 GM. When the app gets EAAccessoryDidDisconnectNotification it will send message [_eaSessionController closeSession];. All these worked nice in iOS 5.1.1 or earler. But on iOS6 with this message I got logs as follows:
-[NSCondition dealloc]: condition (<NSCondition: 0x2e5640> '(null)') deallocated while still in use
Break on _NSLockError() to debug.
Any ideas?
I came across the same issue. This warning is thrown when calling [NSStream close] upon receiving an EAAccessoryDidDisconnectNotification. There should be also some data exchange between the two devices just before the disconnection.
Breaking on _NSLockError will show that at the moment the object is deallocated, some of the threads spawned by the external accessory framework are waiting on conditions. One of those certainly waits on the condition that is being freed, which explains the warning thrown on the console.
I also noticed that the number of threads created by the external accessory framework keeps on growing each time the accessory disconnects then connects, and they seem to be just leaking.
It seems to me that somehow, the external accessory framework does not properly free the resources it allocates, which results in a lot of mess. One of the subsequent effects of this are crashes that happen inside one of those leaked threads during a call to OSAtomicCompareAndSwap64.
I managed to reproduce the issue using a basic sample in which the streams are scheduled on the main thread to avoid any thread management inside the application. I believe it's an accessory management bug on iOS 6 that Apple should be aware of. I'll report it and wait for what they have to say.
Meanwhile, I wonder if anyone of you guys has managed to make any progress on this.
Thanks,
There is no such trouble in iOS 6.1+. To fix this for iOS 6.0 and iOS 6.0.1 please use next solution:
Please note: this is only temp solution allow your users with iOS 6.0 and 6.0.1 continue use your app.
There is a simple hack to avoid application crashes: just create new category and override dealloc method (NSCondition) for iOS 6.0 and iOS 6.0.1:
#import "NSCondition+LeakDealloc.h"
#import <objc/runtime.h>
#implementation NSCondition (LeakDealloc)
- (void) safeDealloc
{
float sVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
if (sVersion < 6.0 || sVersion >= 6.1)
{
[self safeDealloc];
}
}
+ (void) load
{
method_exchangeImplementations(class_getInstanceMethod(self, #selector(dealloc)), class_getInstanceMethod(self, #selector(safeDealloc)));
}
#end
This solution make new leak, after 20 min tests and about 50 BG/FG swithces instruments shows 10 NSCondition leaks (960 Bytes), BUT no one crash!
The issue has been fixed in iOS 6.1.
There are no more leaking NSCondition or external accessory threads. Apple seem to having fixed the issue properly.

How do you programmatically detect your iPad's generation?

I'm working on a program that needs to be able to detect whether or not camera hardware is present in the iPad. I assumed that the easiest way to do this was to determine what generation the device was, but if there is a simpler way to detect the hardware that works too. The iPads that this application is being designed for will likely be recently purchased and running on a standard updated version of iOS.
Nope You can simply check what device is being used!
For checking all iOS devices:
NSString *deviceType = [UIDevice currentDevice].model;
NSLog(deviceType);
In order to check for a camera
if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera])
//there is a camera

Objective-C Scripting Bridge and iTunes

Hi i need a little help i want to include 2 buttons on my Mac App which will trigger 2 actions, 1 will trigger the iTunes shuffle feature and set it to YES but if it is all ready set to YES then it will set it to NO. The other will get iTunes current playback repeat mode.
This is what i have found from the iTunes.h file and also here's a description of the iTunes.h file http://merbist.com/2010/01/17/controlling-itunes-with-macruby/
#property BOOL shuffle; // play the songs in this playlist in random order?
#property iTunesERpt songRepeat; // playback repeat mode
Can anyone help me, thanks Sami.
You need to declare an instance of SBApplication to talk to iTunes:
SBApplication *_iTunes = [[SBApplication applicationWithBundleIdentifier: #"com.apple.itunes"] retain];
Once you have this SBApplication (keep it around in your class), use it to control iTunes directly. For example, to turn on the "Shuffle" mode:
_iTunes.currentPlaylist.shuffle = YES;
will do the trick.