SBJsonParser: memory keeps increasing - json

I'm using SBJsonParser on a project of mine(due to the fact that I have to support Tiger). I'm using the version 3.0.4(it's the last non-ARC version). When I call this everything goes alright:
SBJSON *parser = [[[SBJSON alloc] init] autorelease];
The problem is when I call this:
NSDictionary *dict = [parser objectWithString:[arr objectAtIndex:i]];
Memory goes up and never goes down. If I release the dict, the app crashes. Does anyone know what could be wrong?
Thanks!

Related

Simple Download with CloudRail fails

I am trying to implement an application that includes downloading files from Dropbox. It looks like there is a simple straightforward framework that does that (CloudRail). But the codes crashes when I try to work with the file downloaded (in this case an image), here is the example:
self.dropboxInstance = [[Dropbox alloc] initWithClientId:self.authDic[#“————“] clientSecret:self.authDic[#“————“]];
id returnObject = [self.dropboxInstance downloadWithFilePath:#“/pictures/001.png“];
UIImage * image = [UIImage imageWithData:object]; // CRASH HERE
I checked the network and disk activity through Xcode tools and the download is performed correctly, so I believe it has something to do with the return of the download function.
First of all, the return type of the method is an NSInputStream, that can be used to read the contents of the file you downloaded.
The reason why the code is not working is because you are treating it as an NSData type.
So the solution would be to first read all the content from the stream received as return, store it in an NSData object and then create an UIImage from the data.
self.dropboxInstance = [[Dropbox alloc] initWithClientId:self.authDic[#“————“] clientSecret:self.authDic[#“————“]];
id returnObject = [self.dropboxInstance downloadWithFilePath:#“/pictures/001.png“];
//NEW CODE
NSInputStream * inputStream = returnObject;
[inputStream open];
NSInteger result;
uint8_t buffer[1024]; // buffer of 1kB
while((result = [inputStream read:buffer maxLength:1024]) != 0) {
if(result > 0) {
// buffer contains result bytes of data to be handled
[data appendBytes:buffer length:result];
} else {
// The stream had an error. You can get an NSError object using [iStream streamError]
if (result<0) {
[NSException raise:#"STREAM_ERROR" format:#"%#", [inputStream streamError]];
}
}
}
//END NEWCODE
UIImage * image = [UIImage imageWithData:data]; // NO CRASH ANYMORE :)
The above code is used to read from the stream in a procedural way (will block the thread). To read from the stream asynchronously refer to this other answer (Stream to Get Data - NSInputStream). Hope this helped.

Scan for images in website - Xcode

I am making an app which will give me the latest news, and the image. I achieve the text bit by making a scanner like this.
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
/* set headers, etc. on request if needed */
[request setURL:[NSURL URLWithString:#"http://stackoverflow.com/questions/22671347/nsuinteger-should-not-be-used-in-format-strings"]];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:NULL error:NULL];
NSString *html = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSScanner *scanner = [NSScanner scannerWithString:html];
NSString *token = nil;
[scanner scanUpToString:#"<p>" intoString:NULL];
[scanner scanUpToString:#"</p>" intoString:&token];
int length = 3;
token = [token substringFromIndex:length];
textView.text = token;
Now I was wondering if I could use the same type of code to scan the website to find the first image and put it an image view. Also it don't have to be same type of code , post what ever you know and any method.
Summary is.
Want a piece of code that will scan a webpage, pick up the first image and place it in a image view.
Thanks for the people who take the time to help me.
THANKS AGAIN!!!
BYE!!!
NSScanner its not a HTML parser only intended for scanning values from NSString object. If you doing the odd scan you probably could get away with it, but it doesn't seem like...
The CORRECT approach is to use Libxml2 library included in Xcode which is only written is C which doesn't have any Objective-C/Swift wrapper. Libxml2 is the XML C parser and toolkit developed for the Gnome project. Alternatively i would recommend using open-source project such as HTMLReader. Its a HTML parser with CSS selectors in Objective-C and Foundation. It parses HTML just like a browser and is all written in Objective-c.
Example (using HTMLReader):
HTMLDocument *document = [HTMLDocument documentWithString:html]; // get your html string
NSLog(#"IMG: %#", [document firstNodeMatchingSelector:#"img"].textContent); // => image returned here
To find images just change the tag to < img > and your set!!
IF your using Libxml2 take a look at HTMLparser.c header file to parse and retrieve HTML ltags

Implementing 'Download to Computer' functionality of browser

I am trying to download a mp3 file at a given link using NSURLConnection. However, I usually get time-out errors. Entering the link into the browser shows the default player, however the music file is not loaded either:
However, if I create the following simple HTML file:
<html>
<body>
Download
</body>
</html>
And then load the file into Safari, right click on the Download link, then select Download to Computer (or whathever it's called in English), Safari downloads the file.
Any ideas on how I can implement this in my own app?
I tried using
NSData *data = [NSData dataWithContentsOfURL:url];
and
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *r, NSData *data, NSError *e) { /.../ }];`
without success.
Seems like you're trying to hit a fly with a sledgehammer, using "NSURLConnection".
Try doing something a wee bit more high level such as
NSData * mp3data = [[NSData alloc] initWithContentsOfURL:options:error: ];
(the added benefit here is that you can get useful errors back via the "error:" parameter you pass into the method.
Here's an example on what you need to do:
NSURL* url = [NSURL URLWithString:yourMp3URLString];
//URL of the mp3 file
NSString* fileName = [NSString stringWithFormat:#"%#.mp3", mp3Name];
//NSString with the name of the mp3
NSString* destinationPath = [filePathString stringByAppendingPathComponent:fileName];
//NSString with the filePathString (NSString with path destination, you could
//change it to something like this #"User/Desktop")
//and add the NSString filename to the end of it
//so, if we have like User/Desktop it will become User/Desktop/mp3Name.mp3
NSURLRequest* request = [NSURLRequest requestWithURL:url];
NSURLDownload* download = [[NSURLDownload alloc] initWithRequest:request delegate:self];
[download setDestination:destinationPath allowOverwrite:NO];
//create the URLRequest and Download the mp3 to the destinationPath

UIViewController.navigationController becomes nil

I bumped into a problem where UIViewController.navigationController becomes nil and I'm desperately trying to find an answer to this one.
The UINavigationController gets setup in the application delegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.rootViewController = [[RootViewController alloc] initWithNibName:#"RootView" bundle:nil];
UINavigationController* navigationController = [[UINavigationController alloc] initWithRootViewController:self.rootViewController];
[self.window addSubview:navigationController.view];
[self.window makeKeyAndVisible];
return YES;
}
When the RootViewController is appearing, the self.navigationController member is set and I can use it to hide the navigation bar, like so:
- (void)viewWillAppear:(BOOL)animated {
NSLog( #"self = %#, self.navigationController = %#", self, self.navigationController );
[self.navigationController setNavigationBarHidden:YES animated:NO];
}
The debug output shows values for self and self.navigationController.
When a button is clicked in this controller, self remains the same value indeed but self.navigationController is now nil:
- (IBAction)buttonClicked:(id)sender {
NSLog( #"self = %#, self.navigationController = %#", self, self.navigationController );
// here, self.navigationController is nil, so
// [self.navigationController pushViewController:...] doesn't work :-(
}
I've seen dozens of questions regarding this problem and the answer is always that the UIViewController is not part of a UINavigationController. Since accessing the navigationController in viewWillAppear works fine, I believe something else must be going on. Do you have any pointers? I'll happily provide more detail if necessary.
Try this in the app delegate:
[(UINavigationController *)self.window.rootViewController pushViewController:yourViewController animated:NO];
the rootviewcontroller is actually UINavigationController if you po to debug it. This works for me.
Your code shows that you are only using the navigationController's view but just pray that navigationController life is handled by some magic hand which is not the case.
You need someone to be the explicit owner of the navigationController here.
In fact, the following line:
[self.window addSubview:navigationController.view];
seems to indicate that what you want is for the window's rootViewController to be navigationController:
self.window.rootViewController = navigationController;
But also, it seems that the application's delegate is to be an owner of navigationController as well so navigationController should, in fact, be an ivar of your app's delegate.
In short, fix your object graph (and it will coincidentally do the extra retain you manually did and fix your bug)
I had a problem with a nil view controller and found that it was not connected properly in storyboard to the app delegate.
As always, it helps to formulate the question just to find the solution some minutes later.
I fell prey to ARC, I guess. Once I retained the UINavigationController in the application delegate, it worked fine.

iPhone4 EXC_BAD_ACCESS for UIView after dealloc. How to debug?

I'm working with Apple's Accelerometer Graph Example:
http://developer.apple.com/library/ios/#samplecode/AccelerometerGraph/Introduction/Intro.html
I'm pushing 2 Graph Views onto a navigation controller:
GraphViewController* graphViewController = [[GraphViewController alloc]initWithNibName:#"GraphViewController" bundle:nil];
[self.navigationController pushViewController:graphViewController animated:YES];
[graphViewController release];
The graph's are updated by an external method:
[motionManager startDeviceMotionUpdatesToQueue:motionQueue withHandler:^(CMDeviceMotion *motion, NSError *error) {
...
if(graphDelegate)
{
[self performSelectorInBackground:#selector(notifyGraphDelegateWithMotionEvent:) withObject:motion];
}
}
, which calls
[unfiltered addX:filteredValue y:unfilteredvalue z:10];
for each graph. The frequency of updates is 20 times per second
When I pop the view from the navigation controller, I get EXC_BAD_ACCESS after [super dealloc]
-(void)dealloc
{
// Since 'text' and 'current' are weak references, we do not release them here.
// [super dealloc] will take care to release 'text' as a subview, and releasing 'segments' will release 'current'.
[segments release];
[super dealloc];
}
This is a nasty error, and I really don't know how to troubleshoot something like that. It seems to be something about the order in which the views are de-allocated, as the crash happens after the view is popped. Any ideas on how to troubleshoot something like that?
Set NSZombieEnabled, MallocStackLogging, and guard malloc in the debugger. Then, when your App crashes, type this in the gdb console:
(gdb) info malloc-history 0x543216
Replace 0x543216 with the address of the object that caused the crash, and you will get a much more useful stack trace and it should help you pinpoint the exact line in your code that is causing the problem.
See this article for more detailed instructions.