Posts Tagged Evernote

Evernote Backup – Progress…

I have been working nearly full time on the Evernote backup implementation and things are shaping up nicely. I became inspired by Tweetie 2’s refresh tweets idea so I decided to implement something similar in our app. I have been wondering for a while how we could have a sync button without a sync button and this works perfectly. Simply pull the table view down beyond the end of the list and release. If the user does not want to sync they can push the list back up before releasing and no sync will occur.
The beta testers have been testing it although we do not have as many testers for this round due to my warning to our testers that this may very well wreck your notes. Users are pretty partial to those things so only a few have been brave enough to try it and so far its gone well. None of our testers, to my knowledge, have lost any of their notes, and as an added bonus their notes are making their way to the evernote server and back.
I am hoping to release another beta to our users later this week as we are shooting for a final release to Apple by the end of the month so that we can have something to show off at ETS next month.


Tags: ,

iPhone BibleReader Progress Update

So after a slight delay I finally posted a new beta for our beta testers today. It was a long haul but worth every bit of work in the end. I totally underestimated how much work would need to be done on our end when using someone else’s services. I figured that since they were doing the heavy lifting we had it easy, but I was wrong. There is just as much book keeping on our end as there is on their end. Adding the concept of a trash bin is what really tripped me up and exposed some hidden bugs in our already existing notes system.
See, when I promised a beta last week I had not yet added the trash bin and really didn’t give it much thought, but as I played with the two together I found not having the trash bin on our side was clumsy and short-sighted so I decided to add it. That unraveled everything on my end for a few days and in the end I learned something about myself.
Isn’t God amazing, He uses my simple little problems at work to teach me something about myself. What I learned is that I am easily unsettled and expect everything to go smoothly. I feel like just because I ask God for a good day at work He should grant it. (After all I am doing the Lord’s work, right?) Then I hit these obstacles, and I freak out inside. If you could have seen me (inside) these last few days you would laugh, because I was pretty frantic trying to pin down what ended up being about 3 bugs stacked on top of each other. Funny thing is I should expect that this is going to happen as I write code, that I am human and do not write perfect code, but I don’t always do that, I rarely do that. Instead I freak out that my code does not work and second guess every design decision I have made in the last week. Things might have gone more smoothly had I been a bit more calm inside.
I think I might try that next time.
Matthew 6:25-34
Prov 12:25
1Pe 5:7


Tags: , ,

Evernote Backup Update

Progress on the Evernote backup is moving along quite nicely and I expect to be releasing our first beta with Evernote integration to our beta testers later this afternoon or early tomorrow morning. I am excited to hear their initial reactions and feedback on how to make it better.

Because Evernote is not intended to backup bible notes I had to get creative with the note tags that Evernote does offer, and I think I came up with a simple yet effective system that does not intrude on a user’s experience when using Evernote for notes outside of BibleReader.

Every note has associated with it a category, a verse reference, and an icon. I used tags to store this information, so a note referencing John 3:16 will have a tag [Verse:Jn 3:16]. If that note is in a folder such as “Bible Studies” I create a tag [Category:Bible Studies] and associate the tag with the note. Also it should be noted that in order to keep a user’s notes separate from their bible notes I create a notebook in Evernote called “Bible Notes” and place all the notes we sync from BibleReader in that notebook.

We are trying to make this as open and as generic as possible so that end users do not feel like their notes are forever tied to Olive Tree and so that hopefully other bible programs such as Accordance can make use of the Evernote system and we can have desktop to mobile note synchronization.


Tags: , ,

Notes Backup – update

After having such a successful day yesterday with Evernote I was anxious to get started fleshing out the details of our notes backup implementation. I spent most of the morning beefing up the login code for the Evernote servers. Making sure that we handle all errors without the app just crashing if it encounters one. Then I started looking into the right way to plug in notes backup into BibleReader. It took everything I had in me not to just start hacking away and writing code, but being that I am still a relatively new employee at Olive Tree I am still finding my way through our code base and understanding the structure of how notes are handled by our software. Being that we develop for more than one platform whatever I do needs to be easily plugged into those other ports at some point. We also want to implement a ‘pluggable’ system so that other backup methods can be used as well in the future. So, while I was hoping for a beta by the end of next week, it may be a little longer than that, but it will definitely be worth the wait, I promise. 😉

Tags: , ,

Evernote – Bible Notes Preview

I spent the day having fun with the Evernote API and these are some screenshots showing notes I was able to send from our BibleReader application. Hoping to have a beta out next week.

Showing two notes uploaded from within the BibleReader app.

Showing more detail on a single note uploaded from BibleReader - note the tags are used to keep track of catagory, verse reference, and icon.

Tags: ,

Evernote API Cocoa Example

Disappointed by the lack of Evernote love for the iPhone SDK I decided to port their python example to Cocoa. This code snippet should work with Cocoa and Cocoa Touch.

#import "EvernoteBackup.h"

#import "THTTPClient.h"
#import "TBinaryProtocol.h"
#import "UserStore.h"
#import "NoteStore.h"

@implementation EvernoteBackup

- (void)Test
{
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	// Keep this key private
	NSString *consumerKey = [[[NSString alloc] 
		initWithString: @"YOUR_CONSUMER_KEY_HERE" ] autorelease];
	NSString *consumerSecret = [[[NSString alloc] 
		initWithString: @"YOUR_CONSUMER_SECRET_HERE"] autorelease];
	// For testing we use the sandbox server.
	NSURL *userStoreUri = [[[NSURL alloc] 
		initWithString: @"https://sandbox.evernote.com/edam/user"] autorelease];
	NSString *noteStoreUriBase = [[[NSString alloc] 
		initWithString: @"http://sandbox.evernote.com/edam/note/"] autorelease];
	// These are for test purposes. At some point the user will provide his/her own.
	NSString *username = [[[NSString alloc] 
		initWithString: @"YOUR_USERNAME_HERE"] autorelease];
	NSString *password = [[[NSString alloc] 
		initWithString: @"YOUR_PASSWORD_HERE"] autorelease];

	THTTPClient *userStoreHttpClient = [[[THTTPClient alloc] 
		initWithURL:userStoreUri] autorelease];
	TBinaryProtocol *userStoreProtocol = [[[TBinaryProtocol alloc] 
		initWithTransport:userStoreHttpClient] autorelease];
	EDAMUserStoreClient *userStore = [[[EDAMUserStoreClient alloc] 
		initWithProtocol:userStoreProtocol] autorelease];
	EDAMNotebook* defaultNotebook = NULL;

	BOOL versionOk = [userStore checkVersion:@"Cocoa EDAMTest" :
						[EDAMUserStoreConstants EDAM_VERSION_MAJOR] :
						[EDAMUserStoreConstants EDAM_VERSION_MINOR]];

	if (versionOk == YES)
	{
		EDAMAuthenticationResult* authResult = 
			[userStore authenticate:username :password 
				:consumerKey :consumerSecret];
		EDAMUser *user = [authResult user];
		NSString *authToken = [authResult authenticationToken];
		NSLog(@"Authentication was successful for: %@", [user username]);
		NSLog(@"Authentication token: %@", authToken);

		NSURL *noteStoreUri =  [[[NSURL alloc] 
			initWithString:[NSString stringWithFormat:@"%@%@", 
				noteStoreUriBase, [user shardId]] ]autorelease];
		THTTPClient *noteStoreHttpClient = [[[THTTPClient alloc] 
			initWithURL:noteStoreUri] autorelease];
		TBinaryProtocol *noteStoreProtocol = [[[TBinaryProtocol alloc] 
			initWithTransport:noteStoreHttpClient] autorelease];
		EDAMNoteStoreClient *noteStore = [[[EDAMNoteStoreClient alloc] 
			initWithProtocol:noteStoreProtocol] autorelease];

		NSArray *notebooks = [[noteStore listNotebooks:authToken] autorelease];
		NSLog(@"Found %d notebooks", [notebooks count]);
		for (int i = 0; i < [notebooks count]; i++)
		{
			EDAMNotebook* notebook = (EDAMNotebook*)[notebooks objectAtIndex:i];
			if ([notebook defaultNotebook] == YES)
			{
				defaultNotebook = notebook;
			}
			NSLog(@" * %@", [notebook name]);
		}

		NSLog(@"Creating a new note in default notebook: %@", [defaultNotebook name]);

		// Skipping the image resource section...

		EDAMNote *note = [[[EDAMNote alloc] init] autorelease];
		[note setNotebookGuid:[defaultNotebook guid]];
		[note setTitle:@"Test note from Cocoa Test."];
		NSMutableString* contentString = [[[NSMutableString alloc] init] autorelease];
		[contentString setString:	@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"];
		[contentString appendString:@"<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml.dtd\">"];
		[contentString appendString:@"			<en-note>Here is the Olive Tree Test note.<br/>"];
		[contentString appendString:@"			</en-note>"];		
		[note setContent:contentString];
		[note setCreated:(long long)[[NSDate date] timeIntervalSince1970] * 1000];
		EDAMNote *createdNote = [noteStore createNote:authToken :note];
		if (createdNote != NULL)
		{
			NSLog(@"Created note: %@", [createdNote title]);
		}
	}

	[pool drain];
}

@end

Again your mileage may vary but I think this gives you the gist of how to talk to the Evernote servers.

Tags: , ,

Evernote API and iPhone SDK Setup

I was surprised by the lack of details on this topic so I decided to post my experiences with getting Evernote’s API setup in an iPhone application.

Note: Don’t forget to ask for an Evernote API key.

Steps for geting Evernote API compiling for the iPhone.

1. Grab thrift cocoa runtime:

  
$> svn co http://svn.apache.org/repos/asf/incubator/thrift/trunk/lib/cocoa/src/ thrift-cocoa

2. Grab latest Evernote API from http://www.evernote.com/about/developer/api

$> wget http://www.evernote.com/about/developer/api/evernote-api-1.xx.zip

3. Unzip Evernote API

$> unzip evernote-api-1.xx.zip

4. Go into the evernote cocoa source directory and replace every occurance of <Cocoa/Cocoa.h> with <UIKit/UIKit.h>

$> cd evernote-api-1.13/src/cocoa
$> perl -pi -e 's/<Cocoa\/Cocoa.h>/<UIKit\/UIKit.h>/g' *.h
$> perl -pi -e 's/<Cocoa\/Cocoa.h>/<UIKit\/UIKit.h>/g' *.m

5. Open XCode and add a ‘3rdParty’ group with the group “Evernote” beneath it

6. From the 3rdParty group click “Add existing files” and select the thrift-cocoa folder.

7. Expand the thrift-cocoa folder and delete the references to the folder server and everything contained within it.

8) Expand the transport folder and delete TSocketClient.m & TSocketClient.h (Evernote does not appear to need these and they won’t build with the iPhone SDK.)

9. From the “Evernote” group click “Add existing files” and select the cocoa folder under evernote-1.xx/src/cocoa

10. Try to build the system. I am using 1.13 and for whatever reason the cocoa is borked and needs some massaging. If you get errors like ‘EDAM_MIME_TYPES’ undeclared (first use in this function) then you have two choices. Install boost and thrift idl and run the thrift files in evernote-api-1.xx/src/thrift through thrift and it should generate good files otherwise you need to look at the errors and determine if you can fix them using some simple replacements as I have done below…

# Replaces the erroneous EDAM_ with EDAMEDAM_
$> perl -pi -e 's/ EDAM_/ EDAMEDAM_/g' EDAMLimits.m
$> perl -pi -e 's/ EDAM_/ EDAMEDAM_/g' Types.m
$> perl -pi -e 's/ EDAM_/ EDAMEDAM_/g' UserStore.m
# But this breaks the function definitions so I refix them here.
$> perl -pi -e 's/\+ \(int32_t\) EDAMEDAM_/\+ \(int32_t\) EDAM_/g' EDAMLimits.m
$> perl -pi -e 's/\+ \(NSString \*\) EDAMEDAM_/\+ \(NSString \*\) EDAM_/g' EDAMLimits.m
$> perl -pi -e 's/\+ \(NSSet \*\) EDAMEDAM_/\+ \(NSSet \*\) EDAM_/g' EDAMLimits.m
$> perl -pi -e 's/\+ \(NSString \*\) EDAMEDAM_/\+ \(NSString \*\) EDAM_/g' Types.m
$> perl -pi -e 's/\+ \(int16_t\) EDAMEDAM_/\+ \(int16_t\) EDAM_/g' UserStore.m

Your mileage will vary. 😉

Tags: , ,