iOS Dropbox API "not currently support by MPOAuthConnection" occur after changing user - objective-c

I am trying to use Dropbox API on iOS but I got trapped by the error when I try to use loadMetadata method.
process flow is below..
1.link (UserA)
[[DBSession sharedSession] linkFromController:self];
2.allow authorization on dropbox authorization view
3.unlink (UserA)
[[DBSession sharedSession] unlinkAll];
4.link (UserB)
[[DBSession sharedSession] linkFromController:self];
5.allow authorization on dropbox authorization view
6.loadMetadata
[[self restClient] loadMetadata:path];
But here I get the error:
Terminating app due to uncaught exception 'Unsupported Signature Method', reason:
'The signature method "(null)" is not currently support by MPOAuthConnection'
loadMetaData did work correctly as UserA but it did not work after changing user.
I doubt that the way to unlink could be not enough .. but I do not know.
Please give me any advices in order to solve the problem. Any help will be appreciated.

Migrating the answer above to a proper one.... As #yusaku posted in a comment on his question, this link has the answer: https://forums.dropbox.com/topic.php?id=94511#post-517526
Specifically, Greg K. says:
Make sure you clear all your DBRestClient objects when you unlink. If
you try to use an old DBRestClient object it will cause this problem.
Clearing the old DBRestClient should be a no-brainer, but when it's late and you're following sample code that makes it a persistent class variable, it's easy to skip a brain or two.

Related

Strange SyncServices / iSync console messages when saving ABAddressBook

I'm displaying and editing an ABPerson with an ABPersonView. I do this like so:
ABPerson *person = (ABPerson *)[_addressBook recordForUniqueId:[curDict valueForKey:#"id"]];
[_personView setPerson:person];
[_personView setEditing:YES];
Where _personView is my ABPersonView. When I edit the ABPerson with the ABPersonView and I save the AddressBook:
[ABAddressBook addressBook] save];
It does save and in the AddressBook application I can see its value has changed, but I get these error messages in Xcode and Console:
I first get this:
sandboxd: ([3082]) AddressBookSync(3082) deny file-read-data /Users/xcodeuser/Library/Developer/Xcode/DerivedData/CompanyName-asdxadsafadfqmwqxaagdsfgafguge/Build/Products/Debug
Followed by a lot of this:
sandboxd: ([3035]) AddressBookSync(3035) deny mach-lookup com.apple.syncservices.SyncServer
And it ends with this:
AddressBookSync[3035:707] [0x10011ba50] |ISyncManager|Warning| SyncServer is unavailable: timed out trying to connect
AddressBookSync[3035:707] AddressBookSync (client id: com.apple.AddressBook) error: Exception running AddressBookSync: Timed out waiting for the sync server
AddressBookSync exited with 2
My application is sandboxed and I integrated iCloud.
I have searched but could not find anyone having the same kind of problems, I have tried this:
Using [[ABAddressBook] sharedAddressBook] instead of [[ABAddressBook] addressBook] but I then get an error from the ABPersonView saying the use of sharedAddressBook is deprecated with the ABPersonView.
I added SyncServices framework, didn't help
The code does work though, at least with my iCloud account. Anyone got a clue to why I'm getting these errors? Is it worth a shot trying it with Xcode 4.3 and 10.8? I'm currently running 4.2.1 with Lion.
Thanks!
I've seen exactly this same problem. I believe you are seeing a bug in the Apple frameework.

Why is Mage_Persistent breaking /api/wsdl?soap

I get the following error within Magento CE 1.6.1.0
Warning: session_start() [<a href='function.session-start'>function.session-start</a>]: Cannot send session cookie - headers already sent by (output started at /home/dev/env/var/www/user/dev/wdcastaging/lib/Zend/Controller/Response/Abstract.php:586) in /home/dev/env/var/www/user/dev/wdcastaging/app/code/core/Mage/Core/Model/Session/Abstract/Varien.php on line 119
when accessing /api/soap/?wsdl
Apparently, a session_start() is being attempted after the entire contents of the WSDL file have already been output, resulting in the error.
Why is magento attempting to start a session after outputting all the datums? I'm glad you asked. So it looks like controller_front_send_response_after is being hooked by Mage_Persistent in order to call synchronizePersistentInfo(), which in turn ends up getting that session_start() to fire.
The interesting thing is that this wasn't always happening, initially the WSDL loaded just fine for me, initially I racked my brains to try and see what customization may have been made to our install to cause this, but the tracing I've done seems to indicate that this is all happening entirely inside of core.
We have also experienced a tiny bit of (completely unrelated) strangeness with Mage_Persistent which makes me a little more willing to throw my hands up at this point and SO it.
I've done a bit of searching on SO and have found some questions related to the whole "headers already sent" thing in general, but not this specific case.
Any thoughts?
Oh, and the temporary workaround I have in place is simply disabling Mage_Persistent via the persistent/options/enable config data. I also did a little bit of digging as to whether it might be possible to observe an event in order to disable this module only for the WSDL controller (since that seems to be the only one having problems), but it looks like that module relies exclusively on this config flag to determine it's enabled status.
UPDATE: Bug has been reported: http://www.magentocommerce.com/bug-tracking/issue?issue=13370
I'd report this is a bug to the Magento team. The Magento API controllers all route through standard Magento action controller objects, and all these objects inherit from the Mage_Api_Controller_Action class. This class has a preDispatch method
class Mage_Api_Controller_Action extends Mage_Core_Controller_Front_Action
{
public function preDispatch()
{
$this->getLayout()->setArea('adminhtml');
Mage::app()->setCurrentStore('admin');
$this->setFlag('', self::FLAG_NO_START_SESSION, 1); // Do not start standart session
parent::preDispatch();
return $this;
}
//...
}
which includes setting a flag to ensure normal session handling doesn't start for API methods.
$this->setFlag('', self::FLAG_NO_START_SESSION, 1);
So, it sounds like there's code in synchronizePersistentInf that assumes the existence of a session object, and when it uses it the session is initialized, resulting in the error you've seen. Normally, this isn't a problem as every other controller has initialized a session at this point, but the API controllers explicitly turns it off.
As far as fixes go, your best bet (and probably the quick answer you'll get from Magento support) will be to disable the persistant cart feature for the default configuration setting, but then enable it for specific stores that need it. This will let carts
Coming up with a fix on your own is going to be uncharted territory, and I can't think of a way to do it that isn't terribly hacky/unstable. The most straight forward way would be a class rewrite on the synchronizePersistentInf that calls it's parent method unless you've detected this is an API request.
This answer is not meant to replace the existing answer. But I wanted to drop some code in here in case someone runs into this issue, and comments don't really allow for code formatting.
I went with a simple local code pool override of Mage_Persistent_Model_Observer_Session to exit out of the function for any URL routes that are within /api/*
Not expecting this fix to need to be very long-lived or upgrade-friendly, b/c I'm expecting them to fix this in the next release or so.
public function synchronizePersistentInfo(Varien_Event_Observer $observer)
{
...
if ($request->getRouteName() == 'api') {
return;
}
...
}

ASIHTTPRequest Disabling Cache

I have an application which logs into an online site using POST form being sent from ASIHTTPRequest & ASIFormDataRequest.
I have a log in box, a .xib where user enters their details. Then as they click OK, it connects to the site with the details user has entered. It sends the form OK etc.
But there is a problem. I enter the incorrect details first, it connects and tells me the html of response. I can tell from the html that the details are incorrect. Now i enter the correct details, and ASI* does not even bother connecting.
When I enter the correct details first, it tells me a different html which is supposed to show whenever I enter the right log in details.
So the problem is in cache, because it doesn't bother connecting again on second request, right?
I am using Little Snitch.app, so i know when it connects, and when it does not.
Now, the question sounds: "How do I disable Cache in ASIRequests?"
Thanks a lot.
Snippet of class: http://pastebin.com/a83YCpnm
ASIHTTPRequest doesn't cache POST responses by default - see the following code in ASIHTTPRequest.m
if (![[self requestMethod] isEqualToString:#"GET"]) {
[self setDownloadCache:nil];
}
There's clearly something else going on - are you sure it's a POST request you're making? How are you enabling caching / creating the request, can you post some code please?
Alright I found out what the trouble was. I did not reallocate the ASIFormDataRequest & ASIHTTPRequest on each request, which was causing the trouble on other requests because it was being reused.
Therefore the request has been marked as complete and so it did not even bother making another request if that makes sense.
Thanks

server problem in objective-c

I am hitting an url when the server shutdown.Then the program hang up.May i know how to handle the error when the server shutdown.I mean at that situation I want to give an alert.
Thanks in advance
this is in objective-c
Check reachability api code example in cocoa documentation.
The delegate you supply to an NSURLConnection should handle the error. It will receive the -connection:didFailWithError: message in the event that anything goes wrong. Listing 4 here gives a simple example of just logging the error. If you want an alert dialog to appear you can just sent -presentError: with the NSError as a parameter to a view or a NSDocumentController.

Best Practice - NSError domains and codes for your own project/app

There is a previous SO post regarding setting up error domains for your own frameworks, but what is the best practice regarding setting up error domains and custom error codes for your own project/app?
For example, supposing you're working on a Core Data-intensive app with lots of validations, should you just stick with the "off the shelf" Core Data error codes (such as NSManagedObjectValidationError from CoreDataErrors.h) or should you create your own MyAppErrors.h and define errors with more specificity (i.e., MyAppValidationErrorInvalidCombinationOfLimbs?
Creating a custom error domain and set of error codes could significantly disambiguate your code, but is it too much overhead to maintain and does one have to worry about error code numbering conflicts? Or are there other concerns here?
I personally use a reverse-DNS style domain. For example:
NSError * myInternalError = [NSError errorWithDomain:#"com.davedelong.myproject" code:42 userInfo:someUserInfo];
The third part of the domain (#"myproject") is just used to differentiate the errors from this project ("My Project") from errors in another project ("My Other Project" => com.davedelong.myotherproject).
It's a simple way to ensure that I'm not going to conflict with anyone else's error domains (if I'm using 3rd party code), unless that developer is purposefully trying to mess with just me (which I believe would be highly unlikely...).
As for code numbering conflicts, don't worry about that. Just as long as codes are unique within a domain, you should be OK.
As for translating errors, that's up to you. Whatever you do, make sure you document it well. Personally, I usually just pass on framework-generated errors as they came to me, since I'm never quite sure that I'll handle all the codes and translate all of the userInfo into something more specific to my project. The frameworks could change and add more codes, or change the meaning of existing codes, etc. It also helps me more specifically identify where the error came from. For example, if my StackKit framework generates an error in the com.stackkit domain, I know that it's a framework problem. However, if it generates an error in the NSURLErrorDomain, then I know that it specifically came from the URL loading mechanism.
What you could do is capture the framework generated error and wrap it in a new error object that has your domain and a generic code, something like kFrameworkErrorCodeUnknown or something, and then place the captured error in the userInfo under the NSUnderlyingErrorKey. CoreData does this a lot (for example, if you try to save: an NSManagedObjectContext, but you have relationship integrity errors, you'll get a single error back, but the NSUnderlyingErrorKey will contain much more information, like specifically which relationships are wrong, etc).
I don't have enough rep to comment, but for the accepted answer by Dave DeLong, it might be slightly better to use [[NSBundle mainBundle] bundleIdentifier] instead of #"com.myName.myProject". This way, if you change your name or project's name, it will be reflected accurately.
How to create a custom NSError:
First create a Dictionary of the error message
NSDictionary *userInfo = #{
NSLocalizedDescriptionKey: NSLocalizedString(#"Unknown Error - Please try again", nil),
NSLocalizedFailureReasonErrorKey: NSLocalizedString(#"Unknown Error - Please try again", nil),
NSLocalizedRecoverySuggestionErrorKey: NSLocalizedString(#"Unknown Error - Please try again", nil)
};
NSError *error = [NSError errorWithDomain:[[NSBundle mainBundle] bundleIdentifier]
code:-58 userInfo:userInfo];
Then assign the userInfo to the NSDictionary and your done.