NSUserDefaults crashes when adding empty array - objective-c

I just moved to iOS 8, installed Xcode 6 etc.
This code worked nicely on iOS 7 and 6. It even seems to work on an iPhone 4S with iOS 8 installed. But on iPhones 5 and 5S it crashes. (8.0.0 and 8.0.2 alike)
It does not matter whether the app is build against SDK 7 or 8. It crashes in both cases at the same stage.
The .h file contains:
#property (nonatomic, strong) NSMutableArray* filterBrandsExclude;
from the .m file:
// Following lines just to set the conditions for your understanding:
_filterBrandsExclude = [[NSMutableArray alloc] initWithCapacity:0]; // just creates an empty array.
// As a matter of fact, this array may well be empty and it worked nicely on older iOS versions.
// this line crashes:
[userDefaults setObject:_filterBrandsExclude forKey:#"filterBrandsExclude"];
Error Message:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSKeyValueSlowMutableArray getObjects:range:]: value for key filterBrandsExclude of object 0x17004ae00 is nil'
*** First throw call stack:
(0x1885c6084 0x198bac0e4 0x1885c5fc4 0x18946097c 0x189460a68 0x189460ab0 0x1884c24d0 0x18854be90 0x1884c21c0 0x1884c17e8 0x188627c80 0x188552d9c 0x188551e9c 0x188600290 0x1885ff840 0x1886030e4 0x1893bb750 0x100053e5c 0x1000522a4 0x18cfd65d4 0x18cfdead0 0x18cfdea58 0x18cfd238c 0x1907d1640 0x18857e360 0x18857d468 0x18857ba8c 0x1884a9664 0x1915eb5a4 0x18cdae984 0x1000515f4 0x19921aa08)
libc++abi.dylib: terminating with uncaught exception of type NSException
Any idea is appreciated.

you can manually check
if(self.filterBrandsExclude != nil && self.filterBrandsExclude.count > 0)
[userDefaults setObject:_filterBrandsExclude forKey:#"filterBrandsExclude"];
else
[[NSUserDefaults standardUserDefaults] removeObjectForKey:#"filterBrandsExclude"];

Two things.
In your error it says that the value for the key filterBrandsInclude is nil, but in your question you reference the key filterBrandsExclude. Are you sure you've pinpointed the actual error at this point?
EDIT: Point #2 is invalid.

Related

Crash when setting badge on tab bar in objective C

This line of code crashes. How to check if tabor item is not nil then setting badge?
[self.tabController.tabBar.items objectAtIndex:0].badgeValue = [NSString stringWithFormat:#"%i", num];
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_CTNativeGlyphStorage
tabBar]: unrecognized selector sent to instance 0x15029cfd0'
I checked it by this line of code, but it didn't solve the problem.
if (self.tabController.tabBar.items != nil) { }
If you are setting the badge value before the tab controller is even presented or fully initiated, then there wont be anything at index 0 as yet. There is no need for the tab controller to initiate everything until time comes for presentation, for memory usage purposes. You can keep a reference to each instance of UITabBarItem and set the badge value on them. Or you are going to have to wait until viewDidAppear is called, ensuring all UITabBarItems are fully instantiated...
I cant assume anything else here without seeing the rest of your code.

Is there anyway to check if my app calls any method exclusive for iOS 8?

After testing my app in a iOS 7 device, I got a crash calling containsString from NSString, and then I realised that that methods has NS_AVAILABLE(10_10, 8_0);
Is there anyway to check automatically my program to see if there is any other method that is not available in iOS 7?
How is possible to compile and app with deployment target of 7.0 and not saying any warning or error in these cases?
-[__NSCFString containsString:]: unrecognized selector sent to instance 0x1702297c0
2015-10-23 12:03:37.655 WA[1434:60b] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString containsString:]: unrecognized selector sent to instance 0x1702297c0'
* First throw call stack:
(0x183bd2f50 0x1900dc1fc 0x183bd7c04 0x183bd5930 0x183af55dc 0x1002a2c08 0x1000c71dc 0x1000caa88 0x1000c69bc 0x1000f3a4c 0x186c1055c 0x186c0ff08 0x186c099ec 0x186b9d8cc 0x186b9cad0 0x186c09044 0x1897bb504 0x1897bb030 0x183b92e90 0x183b92df0 0x183b91014 0x183ad1c20 0x186c081c8 0x186c02fdc 0x1000b6040 0x1906cfaa0)
libc++abi.dylib: terminating with uncaught exception of type NSException
You should use rangeOfString instead of containsString. Since rangeOfString available from iOS 2.0, you will not get crash on this.
Code snippets,
NSString *string = #"https://www.google.co.in/";
NSString *substring = #"http";
if ([oneContent rangeOfString:subString].location == NSNotFound) {
NSLog(#"string does not contain substring");
} else {
NSLog(#"string contains substring!");
}
Otherwise you can add category class for NSString and have a method like containsString: where you can implement the above code. It'll work dynamically.

NSString.length causes crash (NSInvalidArgumentException)

I have a iPad app (XCode 6.1.1, iOS 8.1, ARC) that when I run it on the 8.1 simulator, the app crashes comparing the length of a string. This has been running for over a year, and stopped yesterday. This is the code:
This is the code in the .h file:
#property NSString *shopOpenHour;
#property NSString *shopCloseHour;
This is the code in the .m file:
#synthesize shopOpenHour;
#synthesize shopCloseHour;
and:
if(shopOpenHour.length == 0 || shopCloseHour.length == 0) {
and this also causes a crash:
NSLog(#"\n\nlength test: %d", (int)shopCloseHour.length);
This is the error I'm getting:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFNumber length]: unrecognized selector sent to instance 0xb000000000003203'
It runs fine when running under a 7.1 simulator and a iPad running iOS 8.1. I don't understand where/why NSCFNumber is "in the picture".
My question is: any ideas of what's causing this (before I submit a RADAR?)
Somewhere you have assigned a NSNumber to shopCloseHour, it can happen when assigning value from json .Check
if ([shopCloseHour isKindOfClass:[NSString class]]) {
// this is a string …
}

In App Purchase Crashes App

I have an iOS App that I just submitted an update for. The development version of the app (simulator and my 4S) never crashed and it works just fine. The app got approved today as well as the IAP, but I realized this morning that the iAP was not "cleared for purchase". I just cleared it for purchase, but the app still crashes. The error the iPhone gives (running the app store version) gives the error:
<Error>: *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 0 beyond bounds for empty array'
Here is the code where that happens:
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:
(SKProductsResponse *)response
{
NSArray *myProduct = response.products;
//this line is where the error occurs
noAdProduct = [myProduct objectAtIndex:0];
if (![[[NSUserDefaults standardUserDefaults] objectForKey:#"the id here"] boolValue]) {
adCell.detailTextLabel.text = [NSString stringWithFormat:#"$%#", noAdProduct.price];
adCell.userInteractionEnabled = YES;
adCell.accessoryType = UITableViewCellAccessoryNone;
adCell.accessoryView = nil;
[self.tableView reloadData];
}
}
This happens while requesting a list of available products, which obviously returns the product in the simulator but not in the app. I just added a safeguard against this but I will need to submit it to the App Store again.
Does anyone know why the iAP is not showing up for the App Store version? Do I need to wait for the "cleared for sale" option to go to Apple's servers? Thanks!
Obviously myProduct array is empty. Why this happens is another question, but you should never call objectAtIndex without making sure the requested index exists.
if ([myProduct count] > 0)
noAdProduct = [myProduct objectAtIndex:0];
else
// Deal with the situation when the array is empty.

set file's icon in a command line utility not working

I just began to work with Objective-C and I'm managing pretty well. My last challenge was to make a command line utility, which I could than use in AppleScript. But my code does not work, not in the terminal, not in the AppleScript. So I'm asking you, what's the error in this peace of code, that should be very plain and easy?
int main(int argc, char *argv[]) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// -imagePath
// -filePath
NSUserDefaults *args = [NSUserDefaults standardUserDefaults];
NSString *soundPath = [args stringForKey:#"imagePath"];
NSString *filePath = [args stringForKey:#"filePath"];
BOOL worked = [[NSWorkspace sharedWorkspace] setIcon:[[NSImage alloc] initWithContentsOfFile:soundPath] forFile:filePath options:0];
NSLog(#"Worked: %i",worked);
[pool release];
return 0;
}
2010-01-31 17:03:24.317 iConChange[14848:10b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Error (1002) creating CGSWindow'
In effect, that means “You can't do that in a command-line tool”. If you run your tool in the debugger, it'll tell you what “that” is in the stack trace. My guess is that “that” is creating the NSImage.
Another solution is to rewrite the tool to use Icon Services instead of NSWorkspace. The APIs you'll need are still available and not deprecated.
Terminal:
macbook-van-ief2:~ ief2$ /Users/ief2/Desktop/iConChange/build/Debug/iConChange -filePath "~/Desktop/Naamloos.txt" -imagePath "~/Desktop/Z_Home_ZIcon.gif"
2010-01-31 17:03:24.311 iConChange[14848:10b] _NXCreateWindow: error setting window property (1002)
2010-01-31 17:03:24.317 iConChange[14848:10b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Error (1002) creating CGSWindow'
2010-01-31 17:03:24.322 iConChange[14848:10b] Stack: (
2459177131,
2487344699,
2459176587,
2459176650,
2441787103,
2441786331,
2441785537,
2441784212,
2441781861,
2441794711,
2441793509,
2441762807,
2444980701,
2444978472,
2447881218
)
Trace/BPT trap
2010-01-31 17:03:24.317 iConChange[14848:10b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Error (1002) creating CGSWindow'
In effect, that means “You can't do that in a command-line tool”. If you run your tool in the debugger, it'll tell you what “that” is in the stack trace.
One solution is to rewrite it as an application. Perhaps a document-based one, with an image view in the document window, set up to receive dragged images and files.
I have an application that uses basically that code to set icons on OS X:
http://pzich.com/junk/Iconizer.app.zip
I'm not sure why yours isn't working.