No code execution when the method sendAsynchronousRequest of NSRLConnection fails - nsurlconnection

I've implemented this operation:
[NSURLConnection sendAsynchronousRequest:theRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (connectionError) {
NSLog(#"Error %# | contaShow %i",connectionError.description,_contaShow);
//OPERATIONS in case of error
} else {
//OPERATIONS in case of success
Sometime, if occurs a connection error (ex. lost connection) I want execute the code inside the if block.
With debug I can see that the code lines are called, but aren't executed!!!
Somebody can tell me why?!?
Thanks...

If the connection returns an error code (e.g. 404), you'll likely go into the success case, because you need to also check the value of ((NSHTTPURLResponse *)response).statusCode to make sure it is 200.
Beyond that, make sure you're using a debug build. Otherwise, the debugger may lie to you about what lines of code are executing.

Related

Warning: A long-running operation is being executed on the main thread parse [duplicate]

I am getting the error:
"A long-running Parse operation is being executed on the main thread. Break on warnParseOperationOnMainThread() to debug."
and
"Break on warnParseOperationOnMainThread() to debug."
I'm unable to locate the error within my code. Can someone please tell me what I'm doing wrong?
PFQuery *query = [PFQuery queryWithClassName:#"User"];
[query getObjectInBackgroundWithId:[[PFUser currentUser] objectId] block:^(PFObject *object, NSError *error) {
self.firstName = object[#"firstname"];
self.lastName = object[#"lastname"];
self.nameLabel.text = [[NSArray arrayWithObjects:self.firstName, self.lastName, nil] componentsJoinedByString:#" "];
}];
This is a gentle warning to the developers when they make the Parse calls that would block the main thread.
This is where you can see it all happen,, add a symbolic breakpoint on warnBlockingOperationOnMainThread only if you use a Parse API released from 2015+. Otherwise, put it on the warnParseOperationOnMainThread.
It'll break on that function while you are running your code, and will show you a stack trace which should help you to find the blocking function.
See the images below to have a better understanding.
For me this happened when I called:
[[PFUser currentUser] refresh];
The solution was to replace it with:
[[PFUser currentUser] refreshInBackgroundWithBlock:nil];
See also this answer on the Parse Help site.
It Almost happens with all Parse queries or data saving. It avoid this, there is option to perform operation in background. Actually there are two alternatives, one is to perform in background and other is perform in background with block of code.
Maybe it is a bit late, but here you go. I think the problem come from the fact that you are trying to get to objects fetch at the same time:
[[PFUser currentUser] objectId];
and:
[query getObjectInBackgroundWithId...];
It will be better to get the userId first, such as:
//First fetch and store the id in a string so you can reuse it whenever you want
NSString *userId = [PFUser currentUser].objectId;
Second:
// Do your second fetch here:
PFQuery *query = [PFQuery queryWithClassName:#"User"];
[query getObjectInBackgroundWithId:userId block:^(PFObject *object, NSError *error) {
self.firstName = object[#"firstname"];
self.lastName = object[#"lastname"];
self.nameLabel.text = [[NSArray arrayWithObjects:self.firstName, self.lastName, nil] componentsJoinedByString:#" "];
}];
Et voila!

KVO versus NSUndoManager

I have a property on my document class called passDescription, of type NSMutableDictionary. When I call setPassDescription:, the current value of the property is archived into an NSData instance using NSJSONSerialization. The property’s backing ivar, passDescription, is updated, and then an undo action is registered. The selector invoked by the action reconstitutes the NSData given to it and calls setPassDescription:.
Now, here’s the joker: passDescription is being observed using Key-Value Observing. Considerable experimentation and examination in Xcode’s debugger reveals that the old value and the new value are identical. (I know that this isn’t a pointer-aliasing issue, as that’s why I’m using an NSData instance. The NSData is created before I record the new value, making it independent of what it was created from.) Thus, when I press Command-Z to undo, nothing happens as the value that has just been restored is no different from the value that has been overwritten by the undo.
The only thing I can think of that may be causing this is that KVO is setting the passDescription ivar for me, before setPassDescription: gets called. Why would this be, and how could I prevent KVO from doing that? (I have confirmed that the setter isn’t being called twice. If it was, I would see double output in the debugger console.)
Here is the source for setPassDescription:.
- (void)setPassDescription:(NSDictionary *)param
{
NSLog(#"passDescription (before) = \n%#", passDescription);
NSError *error;
NSData *archivedOldValue = [NSJSONSerialization dataWithJSONObject:passDescription options:0 error:&error];
NSAssert(archivedOldValue != nil, #"Could not archive old pass description: %#", error);
NSData *blob = [NSJSONSerialization dataWithJSONObject:param options:NSJSONWritingPrettyPrinted error:&error];
if (blob == nil) #throw [NSException exceptionWithName:#"PBJSONException" reason:#"Could not serialize pass.json" userInfo:#{ #"error": error }];
[self.fileBrowserRoot fileWrapperWithName:#"pass.json"].fileContents = blob;
[passDescriptionLock lock];
[[self.undoManager prepareWithInvocationTarget:self] setPassDescriptionFromData:archivedOldValue];
passDescription = param;
[passDescriptionLock unlock];
NSLog(#"passDescription (after) = \n%#", passDescription);
// After the pass description has been set, refresh the list of build issues.
[self recheckForIssues];
}

initWithContentsOfURL often returns nil

NSError *error;
NSString *string = [[NSString alloc]
initWithContentsOfURL:URL
encoding:NSUTF8StringEncoding
error:&error];
When I test this on my iPhone it always works when I have wifi turned on. However when I'm on 3G I often get nil. If I try perhaps 15 times in a row (I have an update button for this) I finally get the desired result.
My question is, is this problem located at the server side or is my code unstable? Should I use a different approach to get a more secure fetch of data?
You haven't provided enough information to give anything but a vague answer, but you do have some options here.
Most importantly, you have an "error" parameter that you should be printing out the results of. There's also a slightly better API you could be using in the NSString class.
Change your code to something like this:
NSError *error = NULL;
NSStringEncoding actualEncoding;
// variable names in Objective-C should usually start with lower case letters, so change
// URL in your code to "url", or even something more descriptive, like "urlOfOurString"
NSString *string = [[NSString alloc] initWithContentsOfURL:urlOfOurString usedEncoding:&actualEncoding error:&error];
if(string)
{
NSLog( #"hey, I actually got a result of %#", string);
if(actualEncoding != NSUTF8StringEncoding)
{
// I also suspect the string you're trying to load really isn't UTF8
NSLog( #"and look at that, the actual encoding wasn't NSUTF8StringEncoding");
}
} else {
NSLog( #"error when trying to fetch from URL %# - %#", [urlOfOurString absoluteString], [error localizedDescription]);
}
I'm now using STHTTPRequest instead. I recommend this library very much, easy to use yet powerful.

&error error - iOS dev

I am trying to create an AVCaptureSession. I based my code on the WWDC 2011 video, number 419.
I have the following line which is exactly the same as the code in the WWDC 2011 video and it also identical to code here http://www.bardecode.com/en/knowledge-base/214-detailed-description-of-work-around-for-avcapturevideopreviewlayer-problem-in-ios-41.html
// Create a device input with the device and add it to the session.
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device
error:&error];
But Xcode says that the &error is the use of an undeclared identifier.
This is because you've not defined the NSError error variable, that you're providing the address of when you use &error.
If you define the variable via...
NSError *error = nil;
...on the line before, all should be well.
As a bit of an explanation, if you look at the signature for the AVCaptureDeviceInput deviceInputWithDevice:error: method you'll see the following:
+ (id)deviceInputWithDevice:(AVCaptureDevice *)device error:(NSError **)outError
In other words, this method expects the address of an NSError pointer variable to be provided as the ourError parameter.

Re-encoding a NSString returns null

So I have this piece of code :
if ([receivedPage hasPrefix:[NSString stringWithUTF8String:"\xC3\xAF\xC2\xBB\xC2\xBF"]]) // UTF-8 BOM 'EF BB BF' as UTF-16 chars
{
//DebugLog(#"converting calls list to UTF8");
receivedPage = [[[NSString alloc] initWithData:[receivedPage dataUsingEncoding:NSISOLatin1StringEncoding] encoding:NSUTF8StringEncoding] autorelease];
}
However sometimes when the if is true the receivedPage becomes null. why would this happen?
The received page is the returned value of this function:
NSURLResponse * response;
NSData * result = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:error];
if ([result length] > 0)
return [[[NSString alloc] initWithBytes: (const void*)[result bytes] length:[result length] encoding: encoding] autorelease];
else
{
if (error && *error)
DebugLog(#"URL request got error: %#",*error);
return nil;
}
The encoding here is NSISOLatin1StringEncoding (don't know why ,I'm debugging someone else's code).
Any idea why this would happen?
It looks like you're trying to treat strings (objects containing characters) as data (objects containing bytes). Keep the data you received from the connection, and check for the UTF-8 BOM (the proper three-byte version) in it, then use either NSUTF8StringEncoding or NSISOLatin1StringEncoding based on whether you find it.
Or, just use UTF-8 conditionally, if you can fix the server to do that as well.
Also, you should probably switch this code to use the NSURLConnection asynchronously. If the user's internet connection is slow, you're hanging your app here. Doing it asynchronously lets you keep the UI running, display progress if appropriate, and enable the user to cancel.

Resources