How to implement multiple download code objective c - iphone

Im sorry, i feel kind of dumb, but im having trouble implementing the following code for to download multiple files from the server.I have set up the MultipleDownload.h and MultipleDownload.m files as a new Objective-C class within my app. But not sure how call it from my updateView.m to perfrom the file downloads. As per instructions it says i need to initialize and start downloading with the following lines. I cant figure out where to put that code to start downloading files from urls. Do i have to setup a method within that MultipleDownload.m code and call that method it from another object (updateView.m) to initiate the download? or i do i put those lines into one of the methods in (updateView.m)? I honestly tried both and for some reason i keep getting errors, It says that urls. If i put it in updateView.m it says that self.urls and self.downloads is undeclared identifier. I tried to declare NSMutableArray *urls and MultipleDownload *downloads within my updateView.m and it doesnt seen to work either. Any input would be appreciated.
the MultipleDownload.m and MultipleDownload.h code is located on github:
http://github.com/leonho/iphone-libs/tree/master
To initialize and start the download:
self.urls = [NSMutableArray arrayWithObjects:
#"http://maps.google.com/maps/geo?output=json&q=Lai+Chi+Kok,Hong+Kong",
#"http://maps.google.com/maps/geo?output=json&q=Central,Hong+Kong",
#"http://maps.google.com/maps/geo?output=json&q=Wan+Chai,Hong+Kong",
nil];
self.downloads = [[MultipleDownload alloc] initWithUrls: urls];
self.downloads.delegate = self;

What you do is in updateView.h
create #properties for urls (type NSMutableArray) and downloads (type MultiDownload)
then in updateView.m you add a these functions
//Function to start download
- (void) startDownload
{
self.urls = [NSMutableArray arrayWithObjects:
#"YourURLS",
#"YourURLS",
#"YourURLS",
nil];
self.downloads = [[MultipleDownload alloc] initWithUrls: urls];
self.downloads.delegate = self;
}
//download finished for 1 item
- (void) didFinishDownload:(NSNumber*)idx {
NSLog(#"%d download: %#", [idx intValue], [downloads dataAsStringAtIndex: [idx intValue]]);
}
//download finished for all items
- (void) didFinishAllDownload {
NSLog(#"Finished all download!");
[downloads release];
}
I also suggest that if you have problem understanding self.urls and self.downloads to read some more info about objective c and properties, good luck

Related

iPhone zXing QR Scanner - didscanresult function never fires

I have loaded the zXing project into my own project.
It loads fine, the zXing scanner pops up after a button call.
I can dismiss the view controller on thezxingControllerDidCancel but when I scan a QR code, no codes are ever recognised and therefore the didScanResult function never fires.
Does anyone have any idea about this one?
The didScanResult function is below.
-(void)zxingController:(ZXingWidgetController *)controller didScanResult:(NSString *)result{
resultLabel.text = result;
NSLog(#"did scan!!!");
[self dismissModalViewControllerAnimated:NO];
}
Note: I'm not sure if this is relevant, but when the scanner comes up, I get this logged by the app: "wait_fences: failed to receive reply: 10004003"
That tutorial does not mention that you must add a QRCodeReader to the set of readers of your ZXingWidgetController.
ZXingWidgetController has a property called readers, which is an NSSet containing the instances of the readers (e.g. an instance of QRCodeReader). Roughly, the readers' task is to analyze the images your camera takes and to extract the encoded information. Your ZXingWidgetController has to know about the readers it should utilize, otherwise it has no chance to do anything meaningful. So you have to set the readers property before you present the ZXingWidget.
The ZXing project has a sample app which demonstrates this. If you use ARC, then
ZXingWidgetController *widController = [[ZXingWidgetController alloc] initWithDelegate:self showCancel:YES OneDMode:NO];
QRCodeReader* qRCodeReader = [[QRCodeReader alloc] init];
NSSet *readers = [[NSSet alloc] initWithObjects:qRCodeReader,nil];
widController.readers = readers;
[self presentModalViewController:widController animated:YES];
should do.

ObjC object changes to random objects: a memory issue

long time listener, first time caller.
I have a basic memory issue I don't understand, that I'm sure just about any one of you will see in a second. I'm playing around, trying to learn various ways of using UIWebViews, getting strings from URLs, and so on. Specifically, I'm trying to obtain one URL from another. In other words, I have uploaded an html page to the web, containing a URL. The address for that page is coded into the app, giving me a "hook" into the app - I can change the contents of that page and send the app a new URL any time I want. Make sense?
So...retrieving the URL? No problem. Passing it into a string for later use - no problem. But when I set up a tap gesture recognizer, which should take that string, convert it back to an NSURL, and open it in Safari, I get a runtime crash. An NSLog call tells me that the string in question keeps being assigned to all sorts of random things.
The relevant bits of my code follow. I'm sure some of you will tell me there are much better ways to do what I want - and that's certainly welcome. But I'd also really love to know what I'm doing wrong for this particular implementation, as I'm sure it's a basic misunderstanding that I'd like to correct.
Thanks in advance. (And sorry about the formatting of the code block - haven't quite got the hang of posting on here!)
#import "Messing_With_Web_ViewsViewController.h"
#implementation Messing_With_Web_ViewsViewController
#synthesize tapView;
NSString *finalURL;
- (void)viewDidLoad {
[super viewDidLoad];
NSString *firstString = #"http://www.my_web_address.html";
//Of course, I have the correct address here.
NSURL *firstUrl = [NSURL URLWithString:firstString];
NSError * error;
finalURL = [NSString stringWithContentsOfURL:firstUrl
encoding:NSASCIIStringEncoding error:&error];
if ( finalURL )
{
NSLog(#"Text=%#", finalURL);
//everything fine up to here; console prints the correct
contents of "my web address"
}
else
{
NSLog(#"Error = %#", error);
}
//Taps
UITapGestureRecognizer *tapRecognizer;
tapRecognizer=[[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(foundTap:)];
tapRecognizer.numberOfTapsRequired=1;
tapRecognizer.numberOfTouchesRequired=1;
[tapView addGestureRecognizer:tapRecognizer];
[tapRecognizer release];
}
- (void)foundTap:(UITapGestureRecognizer *)recognizer {
NSLog(#"Trying to load %#", finalURL);
//at this point the app either crashes, or the console shows a random memory object
[[UIApplication sharedApplication] openURL:[NSURL URLWithString: finalURL]];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
}
- (void)dealloc {
[finalURL release];
[super dealloc];
}
#end
finalURL = [NSString stringWithContentsOfURL:firstUrl
encoding:NSASCIIStringEncoding error:&error];
The line above creates an instance of NSString which you do not own (because you did not call a method whose name includes 'new', 'alloc' 'retain', or 'copy' on it). That finalURL with therefore eventually be destroyed when it is no longer needed. By the time your -foundTap: method runs finalURL has been deallocated and you are just referencing the memory location where it used to be and which now may contain some other object or random data.
Read the memory management guidelines again and also learn to run the static analyzer which should point out mistakes like this.

Objective C --- Array is readable in a (void) function but not an (IBAction)

Hey all, I have an array that holds all of the .aif file paths in my app, which I found by using mainBundle and resources.
This array needs to be passed down through 2 view controllers to reach where it is actually used. The problem is, it either crashes or logs something totally wrong. When I debug I get an EXC_BAD_ACCESS note at the crash, but not when I run it normally where it just crashes.
Here's the place where it works;
- (void)buildDrumTrigger {
defaultSounds = [[NSArray alloc] initWithObjects: #"kick_3", #"aif", #"snare_1", #"aif", #"HiHat_1", #"aif", #"ride_1", #"aif", #"crash_1", #"aif", #"crash_2", #"aif", #"crash_3", #"aif", #"wave_1", #"aif", nil];
self.DrumObject = [[DrumTrigger alloc] initWithSounds:defaultSounds:5:volumeBox];
[defaultSounds release];
NSLog(#"Possible Sounds: %#", DrumObject.possDrumSounds);
}
That returns a long list of paths that end in fileName.aif. You get the idea.
However...
// Change the current view to the options window.
- (IBAction)goToOptionsView {
NSLog(#"Loading options menu");
NSLog(#"DrumObject.drumSounds: %#", DrumObject.drumSounds);
NSLog(#"DrumObject.possDrumSounds: %#", DrumObject.possDrumSounds);
optionsViewController.soundBox2 = DrumObject.drumSounds;
optionsViewController.possDrumSounds = DrumObject.possDrumSounds;
[self presentModalViewController:optionsViewController animated:YES];
}
That snippet causes a crash. If I comment out the parts where it deals with possDrumSounds, it works fine. Otherwise it crashes or somehow changes the array to contain random objects like UIViewControllers that I have no idea where they came from.
All help appreciated, thanks!
You're probably keeping around array inside of DrumObject without retaining it, so it ends up getting overwritten with garbage.
You're releasing defaultSounds in buildDrumTrigger, so by the time other methods try to access it, it points to data that has been deallocated.
EXC_BAD_ACCESS indicates you're trying to access memory you can't access, normally because you've already released it.

iPhone SDK NSInternalInconsistencyException

I'm hitting a wall over and over again, trying to solve a problem I've got in xcode. I'm a newbie and started coding just a while ago.
I'm trying to make a XML parser based on this tutorial: http://cocoadevblog.com/iphone-tutorial-creating-a-rss-feed-reader
which works fine separately, but when I'm implementing it into my own project, I get the 'NSInternalInconsistencyException' error, as a result of the following code:
----File: Parser.m----
- (void)parserDidEndDocument:(NSXMLParser *)parser {
if ([_delegate respondsToSelector:#selector(parsedInformation::)]){
[_delegate parsedInformation:information];
}else{
[NSException raise:NSInternalInconsistencyException
format:#"Delegate (%d) doesn't respond to parsedInformation:", _delegate];
}
}
I've tried to remove the if-phrase, and then it calls the correct function, but the data which is supposed to be overhanded, won't get through.
Project setup
The project is a tab-based application. I'm having three classes:
Parser
AlphaTab
RootDelegate
In RootDelegate I used the following code to initialize the tab-view, and then to initialiaze the AlphaTab as a tableView being part of a navigationView:
----RootDelegate.m ----
tabBarController = [[UITabBarController alloc] init];
alphaTab = [[AlphaTab alloc] initWithTabTitle:#"AlphaTab" navigationTitle:#"Exploring"];
UINavigationController *tableNavController = [[[UINavigationController alloc] initWithRootViewController:alphaTab] autorelease];
tableNavController.delegate = self;
[alphaTab release]; // creates your table view's navigation controller, then adds the created view controller. Note I then let go of the view controller as the navigation controller now holds onto it for me. This saves memory.
So good so far.. the problem comes when I use the Parser class, which parses a given XML file. This class is initialized and only implemented in the AlphaTab - therefore it has nothing to do with the RootDelegate class at all. The initialization is done as:
----File AlphaTab.m ----
- (void)loadData{
if(information==nil){
Parser *XMLParser = [[Parser alloc] init];
[XMLParser parseFeed:#"http://frederikbrinck.com/bodil/Example.xml" withDelegate:self];
[XMLParser release];
}else {
[self.tableView reloadData];
}
}
I'm suspecting the parameter withDelegate's value "self" to be the problem, which I think referres to the super class RootDelegate, but I'm not sure. Likewise, I don't know to pass the AlphaTab class' delegate to the function, which I think would solve the problem.
I'm ought to think, that the problem could be created from this line aswell:
----FILE: Parser.h ----
#protocol AlphaTab <UITableViewDelegate>
- (void)parsedInformation:(NSArray *)i;
#end
I've done some research about protocols and respondsToSelector, but honestly, I didn't understand much, since my code is seen from the programmatic perspective of view, without using the InterfaceBuilder at all, since I've been adviced to do that. It hasn't lead to the solution of the problem either.
For further understanding, I then want this function in AlphaTab.m to be called, when the information is parsed.
----FILE AlphaTab.m ----
- (void)parsedInformation:(NSArray *)i {
NSLog(#"The parser has completed parsing");
information = i;
NSLog(#"This is the information: %d", [[information objectAtIndex:0] objectForKey:#"tabTitle"]);
[self.tableView reloadData];
}
I've looked on the net, and I found some explications about the NSInternalInconsistencyException. I've tried to do them as well, for example by setting everybody with themselves as delegates. However, I had no luck. What wonders me most, is that when I use the Parser without having to subclass it's caller (this case: AlphaTab) to a main class, it works like a charm.
I hope you guys can give me a clue. If you need any more information please ask, and I'll be in disposition.
//Brinck10
Please see #warrenm and his comment.

Delegate confusion .. How do I find out when several delegates have finished their task?

I've built a basic Web XML to Core Data parsing system, but I am confused about how to set off several parsers at once, and know when they are all done.
This is my current setup, which gets just one parsed xml file ("news"). But I have several xml files I need to parse ("sport", "shop" etc). How would set all of these off, and know when they are all done?
// ViewController.m
DataGrabber *dataGrabber = [[DataGrabber alloc] init];
dataGrabber.delegate = self;
[dataGrabber getData:#"news"];
// DataGrabber delegate method (within ViewController) which gets called when dataGrabber has got all of the XML file
- (void) dataGrabberFinished:(DataGrabber *)dataGrabber
{
NSManagedObjectContext *context = [self managedObjectContext];
NSError *parseError = nil;
// Parser puts the xml into core data. Do I need delegate on this too?
Parser *xmlParse = [[Parser alloc] initWithContext:context];
[xmlParse parseXMLFileWithData:dataGrabber.payload parseError:&parseError];
[xmlParse release];
}
(this a follow-on from this question - Returning data from data-grabbing class from web? )
One option is to count how many you create and then have each one call back to a method that counts down from that total. When its back to zero they are all done.
You will need to set up a delegate for the parser just like you did for the downloader.