iphone NSCondition - App is crashing when "wait" is called - iphone

I am working on iphone app.
I created a custom class that derives from "NSCondition".
The following piece of code is working fine with iPhone SDK 3.1.3
- (bool)waitForFinish {
#try {
[self lock];
while (!done) {
[self wait];
}
}
#finally {
[self unlock];
}
return success;
}
The app is crashing on iPhone SDK 4.0 at line "[self wait]"
What might be the reason for crash in iPhone 4.0 SDK?
I noticed that the loop "while(!done)" is running for 4 times and then its crashing.
//Adding more info
-(void)releaseUse {
[self lock];
#try {
done = 1;
[self broadcast];
}
#finally {
[self unlock];
}
[self notifyComplete];
}
The above function is called when a file is downloaded so that it will send a broadcast message to come out of wait state.
Apple says that in iPhone OS 4, it fixed a bug related to NSCondition. (I don't know what's the bug). I think it might be causing error in iPhone SDK 4 and not in iPhone SDK 3.1

Related

How can I get CTCallCenter Events in an iPhone Enterprise app in the background

I am looking for a way to get CTCallCenter Events on an enterprise app while it is in the background. I came across the suggested solution by OhadM on this post: How to get a call event using CTCallCenter:setCallEventHandler: that occurred while the app was suspended?, but I can't get it to work with the app in the background.
I created a new single view app, added a callCenter property on the appDelegate and set the callEventHandler as shown in the post and listed below. I also added the Voice over IP and Background fetch Background Modes Capabilities as described.
Is there any other settings or code not mentioned in the solution that may help? I am using iOS 9.3.1 and Xcode 7.3.1.
[self.callCenter setCallEventHandler:^(CTCall *call)
{
NSLog(#"Event handler called");
if ([call.callState isEqualToString: CTCallStateConnected])
{
NSLog(#"Connected");
}
else if ([call.callState isEqualToString: CTCallStateDialing])
{
NSLog(#"Dialing");
}
else if ([call.callState isEqualToString: CTCallStateDisconnected])
{
NSLog(#"Disconnected");
} else if ([call.callState isEqualToString: CTCallStateIncoming])
{
NSLog(#"Incomming");
}
}];

Still can't get CoreBluetooth to work in a simple name discovery app

I'm trying to make a simple application that will scan for nearby Bluetooth devices and list their names as they are discovered. I'm using CoreBluetooth in accordance with every guide I've found, including Apple's guide here
However, it never works. I put an iPhone 4S in discoverable mode next to the iPhone 5 running the app, and it never discovers it. I also tried a Bluetooth-enabled car, but I don't know if it has BLE. What am I doing wrong? Here is the essence of my code, in ViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
[activity stopAnimating]; isScanning = NO; //activity is a GUI activity wheel
centralManager = [[CBCentralManager alloc] initWithDelegate: self queue: nil];
}
- (void)centralManagerDidUpdateState:(CBCentralManager *)central{
int state = central.state;
[self log: [NSString stringWithFormat: #"CBCentralManagerDidUpdateState: %d", state]];
//[self log] just NSLogs the message and adds it to a text view for the user to see.
if (state!=CBCentralManagerStatePoweredOn){
[self log: #"Error! Bluetooth not powered on!"]; //I never get this error.
}
}
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI{
[self log: [NSString stringWithFormat: #"Peripheral found with CoreBluetooth: %#", peripheral.name]];
//And I never see any of these "peripheral found" messages.
}
- (IBAction)scanButton:(id)sender {
if (!isScanning){
[activity startAnimating];
isScanning = YES;
[centralManager scanForPeripheralsWithServices:nil options:nil];
[self log: #"Scanning started."];
}
else{
[activity stopAnimating];
isScanning = NO;
[centralManager stopScan];
[self log: #"Scanning stopped."];
}
}
Thanks for any suggestions.
I found an answer here: Can't seem to get core bluetooth to work
I need an iOS device in peripheral mode or a BLE peripheral. Very annoying because basically no peripherals use BLE.
It works with my brother's iPhone 4S running a free app from the App Store called LightBlue. The app lets you put the device in peripheral mode... it's kind of the developer to put out a nice testing app like this.

App Crash due to FB sdk 3.2

I am using new FB IOS SDK and app crash and get below error
Assertion failure in -FBCacheIndex
_updateEntryInDatabaseForKey:entry:, /Users/chrisp/src/ios-sdk/src/FBCacheIndex.m Terminating app due to
uncaught exception 'NSInternalInconsistencyException', reason: ''
* First throw call stack: (0x334072a3 0x3b0a197f 0x3340715d 0x33cdcb13 0x10b3b1 0x10b635 0x10a7bf 0x3b4b911f 0x3b4b899b 0x3b4b8895
0x3b4c7215 0x3b4c73b9 0x3b4eda11 0x3b4ed8a4)
I have made google and found solution like -lsqlite3.0 in other linker flag and add -lsqlite3 framework, FBsession missing. and i have done all but still i am getting same issue.
My code as below:
in FBClass.m which is NSObject type
-(void) getFriendListForInvitation
{
# try {
if (self.friendPickerController == nil) {
// Create friend picker, and get data loaded into it.
self.friendPickerController = [[FBFriendPickerViewController alloc] init];
self.friendPickerController.title = #"Invite Friends";
self.friendPickerController.delegate = self;
[self.friendPickerController clearSelection];
[self.friendPickerController loadData];
self.friendPickerController.itemPicturesEnabled = TRUE;
}
else{
[self.friendPickerController clearSelection];
[self.friendPickerController updateView];
}
self.friendPickerController.allowsMultipleSelection = FALSE;
// iOS 5.0+ apps should use [UIViewController presentViewController:animated:completion:]
// rather than this deprecated method, but we want our samples to run on iOS 4.x as well.
if([[[UIDevice currentDevice] systemVersion] intValue] >= 5.0)
[[[appdelegate.navigationController viewControllers] lastObject] presentViewController:self.friendPickerController animated:TRUE completion:nil];
else
[[[appdelegate.navigationController viewControllers] lastObject] presentModalViewController:self.friendPickerController animated:YES];
}
#catch (NSException *exception) {
NSLog(#"%#",[exception description]);
}
}
Please help me to solve this issue.....
thanks
Did you manage to solve the issue? I suffer from the same problem.
I determined that this exception is caused by the missing file cache.db in the directory facebook is addressing to. You can check that with the help of the simulator. The directory of the missing simulator file is:
/Users/<user name>/Library/Application Support/iPhone Simulator/6.1/Applications/<app id>/Library/Caches/DataDiskCache
Yet I do not know why the file is missing.
EDIT:
The only thing I came up with was to clear the session data from the app with simple two lines of code:
FBSession.activeSession = nil;
[[NSUserDefaults standardUserDefaults] removeObjectForKey:#"FBAccessTokenInformationKey"];
Unfortunately this solution never actually closes the session but at least it is providing the proper workflow of the app.

What will happen to users running a lower version of IOS if new code is called?

I am fairly new to iOS Development and I've always wondered if a user running my application on iOS 4 were to try and run this code:
//POST TWEET//
- (void)showTweetSheet
{
TWTweetComposeViewController *tweetSheet =
[[TWTweetComposeViewController alloc] init];
tweetSheet.completionHandler = ^(TWTweetComposeViewControllerResult result) {
switch(result) {
case TWTweetComposeViewControllerResultCancelled:
break;
case TWTweetComposeViewControllerResultDone:
break;
}
dispatch_async(dispatch_get_main_queue(), ^{
[self dismissViewControllerAnimated:YES completion:^{
NSLog(#"Tweet Sheet has been dismissed.");
}];
});
};
[tweetSheet setInitialText:#"Check out this cool picture I found on #Pickr_"];
// Add an URL to the Tweet. You can add multiple URLs.
if (![tweetSheet addURL:[NSURL URLWithString:ImageHost]]){
NSLog(#"Unable to add the URL!");
}
[self presentViewController:tweetSheet animated:YES completion:^{
NSLog(#"Tweet sheet has been presented.");
}];
}
What would happen? Would the application just terminate with an error or will the code just not run? And how do I properly implement features that are OS specific? Would I just use something like this:
NSString *DeviceVersion = [[UIDevice currentDevice] systemVersion];
int DeviceVersionInt = [DeviceVersion intValue];
if (DeviceVersionInt > 5)
{
//do something.
}
else
{
//don't do a thing.
}
It will crash on iOS 4 if you write iOS5 features without checking if they are available or not. Try to implement Twitter like this
Class twClass = NSClassFromString(#"TWTweetComposeViewController");
if (!twClass) // Framework not available, older iOS
{
//use iOS4 SDK to implement Twitter framework
}
else {
//use Apple provided default Twitter framework
}
Make sure you have added Twitter Framework with weak link.
Id imagine that it would work the same as with any other api. If you link against a function which is not in a previous version, the program will crash on an attempt to call the function. Therefore, version switches are used, as you demonstrated, to avoid crashes.
The app would crash. If you want to implement features based on iOS, you can use a variety of methods. See this question.

Iphone : Application crash because of old encodeObject after updating

Currently, my Iphone application is not released yet. When I worked with the simulator/device and I modify my application to add more cache into the encodeWithCode: and initWithCoder: . The problem is that when the application is loaded, I tried to use some of the encoded object which is not existing before. For example:
In the previous application version (e.g 1.2), I have this encode:
- (void)encodeWithCoder:(NSCoder*)coder {
[coder encodeObject:myArray forKey:NCITEMTABLE_ARCHIVE_HOME_ITEMS_KEY];
}
But with new version (e.g 1.3), I use this init:
- (id)initWithCoder:(NSCoder*)coder {
if (self = [super initWithCoder:coder]) {
myArray = [[coder decodeObjectForKey:NCITEMTABLE_ARCHIVE_HOME_ITEMS_KEY] retain];
myArray2 = [[coder decodeObjectForKey:NCITEMTABLE_ARCHIVE_HOME_ITEMS_2_KEY] retain];
}
return self;
}
and then the application will crash because it cannot find myArray2.
In the simulator or testing, I can just delete the old version and install from fresh. However, I am afraid that when it is released, I cannot tell my user to delete the old app and install the new fresh one. Have anyone experienced about this problem?
In your initWithCoder you should be able to just call containsValueForKey to see if the key exists before trying to call decodeObjectForKey
I tried to use try catch to get the exception. It may not be the best answer but it works now
. The problem is that it may have low performance when it has to do try catch exception, which is not recommended by Apple
if (archive) {
#try {
[self unarchiveInitializingWithData:archive];
}
#catch (NSException * e) {
NCLog (#"Cannot unarchive");
[self normalInitializing];
}
} else {
NCLog (#"Normal init");
// normal init
[self normalInitializing];
}