evernote-cloud-sdk-ios icon indicating copy to clipboard operation
evernote-cloud-sdk-ios copied to clipboard

Evernote IOS SDK fetchResourceByHashWith throws exception

Open AndroidGecko opened this issue 6 years ago • 2 comments

Working with Evernote IOS SDK 3.0 I would like to retrieve a specific resource from note using

fetchResourceByHashWith

This is how I am using it. Just for this example, to be 100% sure about the hash being correct I first download the note with a single resource using fetchNote and then request this resource using its unique hash using fetchResourceByHashWith (hash looks correct when I print it)

ENSession.shared.primaryNoteStore()?.fetchNote(withGuid: guid, includingContent: true, resourceOptions: ENResourceFetchOption.includeData, completion: { note, error in
            if error != nil {
                print(error)
                seal.reject(error!)
            } else {
                let hash = note?.resources[0].data.bodyHash
                ENSession.shared.primaryNoteStore()?.fetchResourceByHashWith(guid: guid, contentHash: hash, options: ENResourceFetchOption.includeData, completion: { res, error in
                    if error != nil {
                        print(error)
                        seal.reject(error!)
                    } else {
                        print("works")
                        seal.fulfill(res!)
                    }})
            }
        })

Call to fetchResourceByHashWith fails with

Optional(Error Domain=ENErrorDomain Code=0 "Unknown error" UserInfo={EDAMErrorCode=0, NSLocalizedDescription=Unknown error})

The equivalent setup works on Android SDK. Everything else works so far in IOS SDK (chunkSync, auth, getting notebooks etc.. so this is not an issue with auth tokens)

would be great to know if this is an sdk bug or I am still doing something wrong.

Thanks

AndroidGecko avatar Feb 13 '19 10:02 AndroidGecko

SO with bounty https://stackoverflow.com/questions/54668021/evernote-ios-sdk-fetchresourcebyhashwith-throws-exception would love to know if this is a bug or I am still doing something wrong

AndroidGecko avatar Feb 15 '19 12:02 AndroidGecko

@AndroidGecko It's a bug. The issue is detailed in an answer to your SO post. Reposting here so someone at Evernote can address it properly:

This is a bug in the SDK's "EDAM" Thrift client stub code. You are invoking the underlying getResourceByHash API method on the note store, which is defined per the docs to accept a string type for the contentHash argument. But it turns out the client is sending the hash value as a binary typed field instead (which is indeed what the text of the documentation suggests should be happening).

If you dig into the more recent Python version of the SDK, you can see a peculiar pattern for this method: it says it's going to write a STRING-type field, and then actually writes a binary one:

    if self.contentHash is not None:
        oprot.writeFieldBegin('contentHash', TType.STRING, 3)
        oprot.writeBinary(self.contentHash)
        oprot.writeFieldEnd()

You see a similar pattern in the Android/Java EDAM layer. Weirdly, that pattern works, effectively sending a chimera string/binary type for the contentHash argument. And if you hack up the iOS SDK to do the same thing, it will work, too.

The bug is either in the Thrift definition/implementation or in the iOS client, but either way the two are mismatched. Marking the field as type string but then actually writing binary data does appear to work correctly, and you can hack up the iOS client to do this if you need to.

bzotto avatar Feb 15 '19 20:02 bzotto