Works on iOS Simulator but not on iOS device? - iphone

EDIT: It works but it takes amazingly long to complete.
Is this normal, or is there a way to optimize it?
Thanks
I am using DDUnitConverter in my project to convert currencies.
Everything works perfectly fine on the iOS Simulator but hangs when I try to convert the currencies on my iOS Device (iPhone 4 iOSv5.1). I looked around to find a fix to this issue but could not find anything. Here is the code that I use to exchange the currencies. The code within the DDUnitConverter is available here: https://github.com/davedelong/DDUnitConverter/downloads
if ([Number.text isEqualToString:#""] || [picklable.text isEqualToString:#"no selection"] || [picklable2.text isEqualToString:#"no selection"]) {
return;
}
if ([Number.text isEqualToString:#"0"]) {
Result.text = #"0";
return;
}
int fromType;
int toType;
fromType = [list indexOfObject:picklable.text];
toType = [list indexOfObject:picklable2.text];
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber * from = [[f numberFromString:Number.text] retain];
[f release];
NSNumber *to = [[[DDUnitConverter currencyUnitConverter] convertNumber:from fromUnit:fromType toUnit:toType] retain];
float toto = [to floatValue];
Result.text = [NSString stringWithFormat:#"%.4f %#", toto, picklable2.text];
if ((toto == 0 || toto == [Number.text floatValue]) && picklable.text != picklable2.text ) {
Result.text = #"No Internet Connection or Previous Data";
}
[from release];
[to release];
[Result flashScrollIndicators];
Hopefully someone can help me out,
Thanks

Your code seems OK to me, but you are using DDUnitConverter. I've never used it, but I suppose it needs internet connection to load data from the internet. If the server take long time to answer, your app could hang on connection.
You can try to connect to the server asynchronously using dispatch_async, this lets your app download data in background.

Anything taking amazingly long to do should be dispatched. Like this:
dispatch_async(dispatch_get_global_queue(), ^(void) {
[self doReallyAmazinglyComplicatedProcessing];
});

Related

reading certificate from a smart card in Xcode using objective-C

I'm new to Objective-C coding and for smart card programming as well. I'm developing application for iPhone. I found a difficulty reading a file from a smart card using iSmartSDK it returns NULL, though the selection of Applet is successful.
Does anyone faced such problem or know about this ? thanks
t0Command.classByte = 0;
t0Command.instructionByte = 0xCB;
t0Command.parameter1Byte = 0x3F;
t0Command.parameter2Byte = 0xFF;
t0Command.dataBytes = nil;
t0Command.lengthByte = t0Command.dataBytes.length;
t0Command.expectedResponseLengthByte = 0x7F;
t0Command.dataBytes = [self hexStringToBytes:#"5C035FC105"];
t0Command.commandId = READ_WRITE_CPU_CARD_COMMAND_ID;
resultCommand = [iSmartInstance sendCommandToCPUCard:t0Command];
if (resultCommand == nil) {
[self displayMessage:#"Read Binary Failed"];
}
else{
[self displayMessage:[NSString stringWithFormat:#"Read Status: %02x%02x", ((T0Command*)resultCommand).status1Byte, ((T0Command*)resultCommand).status2Byte]];
[self displayMessage:[NSString stringWithFormat:#"Response Length: %d", ((T0Command*)resultCommand).dataBytes.length]];
NSString *readBytes = [[[NSString alloc] initWithBytes:((T0Command*)resultCommand).dataBytes.bytes
length:((T0Command*)resultCommand).dataBytes.length
encoding:NSASCIIStringEncoding] autorelease];
[self displayMessage:[NSString stringWithFormat:#"Read Value: %# \n Bytes: %#", readBytes, ((T0Command*)resultCommand).dataBytes.bytes]];
}

Adding large numbers of properties in Core Data, crashing when starting from phone but not from Xcode

I am trying to add data to CoreData. It works fine when I build from Xcode to the phone but when I try to start the app directly from iPhone it crashes on first save to the Context.
I read a text file that is synced via iTunes File Sharing, the file is pretty big (~350 000 lines). The values I get from the file is added to two different arrays (barcodes and productNames). The arrays are later batched through and the sent to the function where I save the data.
From the array loop:
[...]
words = [rawText componentsSeparatedByString:#";"];
int loopCounter = 0;
int loopLimit = 20000;
int n = 0;
int wordType;
NSEnumerator *word = [words objectEnumerator];
NSLog(#"Create arrays");
while(tmpWord = [word nextObject]) {
if ([tmpWord isEqualToString: #""] || [tmpWord isEqualToString: #"\r\n"]) {
// NSLog(#"%#*** NOTHING *** ",tmpWord);
}else {
n++;
wordType = n%2;
if (wordType == kBarcode) {
[barcodes addObject: tmpWord];
}else if (wordType == kProduct) {
[productNames addObject: tmpWord];
}
// Send to batch //
loopCounter ++;
if (loopCounter == loopLimit) {
loopCounter = 0;
NSLog(#"adding new batch");
[self addBatchOfData];
[barcodes release];
[productNames release];
barcodes = [[NSMutableArray arrayWithCapacity:20000] retain];
productNames = [[NSMutableArray arrayWithCapacity:20000] retain];
}
}
[...]
And then the save-function:
-(void)addBatchOfData {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSError *error;
NSUInteger loopLimit = 5000;
NSUInteger loopCounter = 0;
NSString *ean;
NSString *designation;
for (int i=0; i<[barcodes count];i++ ) {
ean = [barcodes objectAtIndex:i];
designation = [productNames objectAtIndex:i];
Product *product = (Product *)[NSEntityDescription insertNewObjectForEntityForName:#"Product" inManagedObjectContext:importContext];
[product setDesignation:designation];
[product setBarcode:ean];
loopCounter ++;
if (loopCounter == loopLimit) {
NSLog(#"Save CoreData");
[importContext save:&error];
[importContext reset];
[pool drain];
pool = [[NSAutoreleasePool alloc] init];
loopCounter = 0;
}
}
// Save any remaining records
if (loopCounter != 0) {
[importContext save:&error];
[importContext reset];
}
[pool drain];
}
It's really irritating that it works fine when I build from Xcode. Hopefully there is a setting that I missed or something...
EDIT: Forgot to mention that I don't get passed the Default-screen and I don't have any logs. Can it have something to do with the provisioning?
Offload your file loading in a background thread and let the phone start up your main window and view. iOS will kill your app if you do not present a view in a timely manor (this is what you are seeing).
I have to do something like this for my xml -> CoreData converter code. I just present the user with a view notifying them of what is going on and a progress bar (I use https://github.com/matej/MBProgressHUD).
something like:
self.hud = [[MBProgressHUD alloc] initWithView:window];
// Set determinate mode
hud.mode = MBProgressHUDModeDeterminate;
hud.delegate = self;
hud.labelText = #"Converting Data File";
[self.window addSubview:hud];
// Show the HUD while the provided method executes in a new thread
[hud showWhileExecuting:#selector(convertToCoreDataStoreTask) onTarget:self withObject:nil animated:YES];
You just have to make sure that you use a separate NSManagedObjectContext in the new thread.
I would suggest that you implement this delegate method and then try to see what is going on with memory.
when running in the simulator, you have no memory constraints, but when running in the phone you do
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
{
}
I think I find the solution to my question.
What I was doing was that I started all the heavy data crunch in the "- (void) viewDidLoad {". When I changed it to start the crunch after I clicked a button in the app, it worked just fine.
Right now it's just finding out where the start the data crunch, any suggestions?

Why do I get SIGABRT after the first iteration of this my for loop?

I feel very stupid for asking this, but I've been trying to figure this for about three hours and have gotten nowhere. See the code below. After the first iteration, my program crashes and all I get is SIGABRT. As you may get from the code, I'm just trying to build a string from other strings. It works fine on the first iteration, but on the second one, it just aborts.
Film* film = (Film *)managedObject;
for (NSManagedObject* crewMember in [film CastAndCrew])
{
castAndCrewMember = (CastOrCrewMember*)crewMember;
if ([[[castAndCrewMember talentType] typeName] isEqualToString:#"Director"])
{
fullName = [[NSMutableString alloc] initWithString:[[castAndCrewMember talent] firstName]];
[fullName appendString:[#" " stringByAppendingString:[[castAndCrewMember talent] lastName]]];
subtitle = [[NSMutableString alloc] initWithString:[[[[fullName description] stringByAppendingString:#" "] stringByAppendingString:[film runningTime]] stringByAppendingString:#" | "]];
[subtitle appendString:[[film category] categoryName]];
[subtitle retain];
[fullName release];
fullName = nil;
break;
}
}
TTTableItem* tableItem = [TTTableSubtitleItem itemWithText:[film title]
subtitle:subtitle
imageURL:[film imageURL]
defaultImage:[UIImage imageNamed:#"aff2010_l.png"]
URL:nil
accessoryURL:nil];
Thanks in advance.
Sorry, guys, I think I found my error. The record that's being returned for the castAndCrew object actually doesn't exist. My bad. Sorry :)

Iphone substring causing memory leak

Im just wrapping up my app, so im onto the stage of running instruments to identify leaks in the app. Ive come across a leak that I cannot work out why it is being registered as a leak.
I have the following lines for example:
NSString *imageType = [[[NSString alloc] initWithString:[loopString substringToIndex:[loopString rangeOfString:#"</IMAGE>"].location]] autorelease];
imageType = [imageType substringFromIndex:[imageType rangeOfString:#"<IMAGE>"].location + :#"<IMAGE>".length];
So basically all im doing is pulling out a section of the "loopstring" and putting that into the imagetype string than just cutting off the trailing fluff of the string using the SubstringFromIndex method.
When I run instruments it says "NSCFString substringwithRange" leak. It highlights the second line:
imageType = [imageType substringFromIndex:[imageType rangeOfString:#"<IMAGE>"].location + :#"<IMAGE>".length];
I would think the substringFromIndex method should return a string that is automatically added to the autorelease pool.
Any ideas on where im going wrong?
Thanks
Following is the refactored code:
- (void)SetupTop10:(NSString *)Top10Data
{
while (Top10Data != #"") {
NSLog(Top10Data);
if ([Top10Data rangeOfString:#"</TOP10ENTRY>"].location == NSNotFound){
Top10Data = #"";
}
else
{
NSString *loopString = [Top10Data substringToIndex:[Top10Data rangeOfString:#"</TOP10ENTRY>"].location + 13];
Top10Data = [Top10Data stringByReplacingOccurrencesOfString:loopString withString:#""];
//NOW CREATE A RECORD FOR THIS ITEM
NSString *imageType = [loopString substringToIndex:[loopString rangeOfString:#"</IMAGE>"].location];
imageType = [imageType substringFromIndex:[imageType rangeOfString:#"<IMAGE>"].location + 7];
NSString *displayText = [loopString substringToIndex:[loopString rangeOfString:#"</DISPLAYTEXT>"].location];
displayText = [displayText substringFromIndex:[displayText rangeOfString:#"<DISPLAYTEXT>"].location + 13];
NSString *link = [loopString substringToIndex:[loopString rangeOfString:#"</INTERESTID>"].location];
link = [link substringFromIndex:[link rangeOfString:#"<INTERESTID>"].location + 12];
[Top10Images addObject:imageType];
[Top10Links addObject:link];
[Top10s addObject:displayText];
Top10RowCount = Top10RowCount + 1;
}
}
[self.Top10Table reloadData];
Top10Table.hidden = NO;
loadingLabel.hidden = YES;
loadingIndicator.hidden = YES;
}
//******************
It doesn't look leaky. But why
NSString *imageType = [[[NSString alloc] initWithString:
[loopString substringToIndex:[loopString
rangeOfString:#"</IMAGE>"].location]
] autorelease];
if you effectively get the same with
NSString *imageType = [loopString substringToIndex:[loopString
rangeOfString:#"</IMAGE>"].location];
with half the memory usage?
Leaks will tell you where the leaked memory was allocated. If you click around (there's a right-arrow icon by the memory address, I think) then you can look at all the allocations/retains/releases for that addresses.
In this example, Leaks will point you to the first line, when it's the fifth one that "leaks" (actually it's a missing release in dealloc/on assignment that leaks):
NSString * s = [someString substringFromIndex:1];
[myArray addObject:s];
// ...
NSString * s2 = [myArray lastObject];
instanceVariable = [s2 retain];
// ... and forget to release in dealloc
What does tableView:cellForRowAtIndexPath: do?
I can't see any problem in the above code. Did you release Top10Images in your dealloc method?

Object in Array is not recognised as having "methods"

I got my application working Awhile back, but after completely and accidentally deleting it, I have tried to create it from square one. unfortunately my rewritten program is a bit cranky; does anyone see or know the possible sources of error? Also, my if statements are acting up.
-(void)loadAnnotations
{
CLLocationCoordinate2D workingCoordinate;
iProspectLiteAppDelegate *appDelegate = (iProspectLiteAppDelegate *)[[UIApplication sharedApplication] delegate];
NSMutableArray *mines =[[NSMutableArray alloc] initWithArray:(NSMutableArray *) appDelegate.mines];
BOOL gold = [[NSUserDefaults standardUserDefaults] boolForKey:#"goldControl"];
BOOL silver = [[NSUserDefaults standardUserDefaults] boolForKey:#"silverControl"];
BOOL copper = [[NSUserDefaults standardUserDefaults] boolForKey:#"copperControl"];
for(id mine in mines)
{
NSLog(#"in the loop");
workingCoordinate.latitude = [[mine latitudeInitial] doubleValue];
workingCoordinate.longitude = [[mine longitudeInitial] doubleValue];
iProspectLiteAnnotation *tempMine = [[iProspectLiteAnnotation alloc] initWithCoordinate:workingCoordinate];
[tempMine setTite:[mine mineName]];
if ([[mine commodity] isEqualToString:#"Gold"] && [gold == YES])
{
[tempMine setAnnotationType:iProspectLiteAnnotationTypeGold];
[mapView addAnnotation:tempMine];
}
if([[mine commodity] isEqualToString:#"Silver"] && [silver == YES])
{
[tempMine setAnnotationType:iProspectLiteAnnotationTypeSilver];
}
if([[mine commodity] isEqualToString:#"Copper"] && [copper == YES])
{
[tempMine setAnnotationType:iProspectLiteAnnotationTypeCopper];
}
}
[mines dealloc];
}
where the workingCoordinate.latitude = [[mine latitudeInitial] doubleValue], as well as the longitude, and [mine mineName],it says " No '-latitudeInitiallongitudeInitial' method found" or the mineName/LongitudeInitial.
also, it complains about : before ] at all the if statement lines. I don't see any errors, do you?
You are using an iterator that is giving you objects of type id - calling a method on those will often confuse a compiler. Are you able to cast them to a known type?
Like for(MineType* mine in mines)?
And
[tempMine setTite:[mine mineName]];
Is that a typo? My guess is you would be calling that method setTitle.
i think changing the object type of mine object in the for loop to whatever custom class you have with latitudeInitial, longitudeInitial, mineName properties/methods should solve this.