ReadNow 2

I’ve pulled ReadNow from the Mac App Store because of an infringement letter. In my current situation I’m not allowed to provide any further information.

I’m very sorry, but ReadNow is not available for download until the future of it is completely clarified.


It was very quiet about ReadNow in the last weeks, but this was for a reason. I’ve worked very hard and are really happy to announce that ReadNow 2 will be released today. It’s available on the Mac App Store and a free update for all current ReadNow users.

This is the biggest update since the first release of ReadNow about 1.5 years ago. In the following I will introduce some changes and new features of ReadNow 2.

Completly redesigned User Interface

First of all, ReadNow has a complete new design as well as a complete new menubar and application icon. It’s also no menubar only application anymore.

Minimalistic

ReadNows Main Window is now fully customizable in the window size or the way bookmarks, folders and the associated articles should be displayed.

Article View

Furthermore the Article View is completly redesigned. It’s fully customizable to fullfill the personal reading expectations and extend the experience to read full articles within ReadNow. The Article View also supports 3 themes: Paper, Light and Dark.

Multiple Accounts Support

Manage one Instapaper and one Read It Later account at the same time.

Offline Mode

A next big change is the offline mode. It’s now more like the iOS application of your read later service of choice. All articles of bookmarks will be downloaded and cached to have access also if the Mac is offline. Actions like archiving / unarchiving or liking / unliking of bookmarks will be saved too and the changes will be pushed to the service in the next bookmarks syncing cyclus.

Drag and Drop

Faster change of bookmark folder or assign tags. Just drag and drop a bookmark onto a folder or tag and it will be moved to this folder or the tag will be assigned.

Sharing

New sharing services are available. With ReadNow 2 sharing bookmarks on Twitter, Facebook, Pinboard, Delicious and Evernote is integrated and it’s planned to extend it to further services in upcoming updates.

Other changes:

- Search in the Article View
- Tag autocompletion in the edit window
- Redownload article
- Second click menubar icon menu
- Folder management for Instapaper

ReadNow and Instapaper

It seems like there are a lot of confusion about ReadNow and the interaction with Instapaper, I hope this post will clear these confusion:

I you would like to use ReadNow with Instapaper
or
I tried to login with my username and password into the Instapaper website a few times, which was no problem. The error message was:
=====
An Instapaper subscription is required, for further information check out http://blog.instapaper.com/post/3208433429
=====

To use ReadNow with Instapaper you need to have a subscriber account at Instapaper. The subscriber account is NOT only a regular accout you have also to pay 1$/month for a Subscription membership. The reason of that is that all developers can use the Full Instapaper API (ReadNow need this), but it will only work for customers with Instapaper’s $1/month Subscription memberships.

How do I purchase a subscription?
Visit http://instapaper.com, click Create Account in the upper right corner, then after creating a new account click the “subscribe” link or visit http://instapaper.com/subscription

Further Details
For further details please also look at the following blog post on the instapaper blog: http://blog.instapaper.com/post/3208433429. This blog post will give you additional details, why this Subscription membership is necessary.

ReadNow: App Store Announcement

The launch of the Mac App Store is right around the corner and I want to take this time to provide some insight on the future of ReadNow. After careful consideration, I have decided that ReadNow will be available through the Mac App Store. It will be available to purchase for $3.99 USD.

Why are you charging for ReadNow?
I’ve developed ReadNow in the last several month and a great deal of work has been put into it to make it at it is now. Several long nights have been put into developing new features and improving on the old as well as correct a lot of bug reports of feature requests from the version 0.x users. If you choose to purchase from the Mac App Store you will not only be showing your support but also helping to provide a foundation for even more to come.

Furthermore I’m a student and don’t have the same resources on time and money as a full time developer, so the revenue also goes towards support for further development of ReadNow or other projects as well as the Mac Developer Account that privileges me to submit ReadNow in the Mac App Store which costs $99 USD/year.

Will you provide a free version of ReadNow?
After the release of ReadNow in the Mac App Store I plan to provide a version of ReadNow with reduced features free of charge on my website.

Michael Schneider

A Custom Sliding Text View

I’m currently in the process to implement a preview window in ReadNow. One of my ideas was to implement a sliding text at the bottom of the window, because lots of websites have a title that is longer than the window. The view should slide the text to the right side till the end of the text and then back to the beginning of the text. Another requirement was that it should be very easy to change the text.
First I thought it will be not so much complicated to implement that, but I was wrong. I tried several of options, like to slide a text within a NSScrollView, but no one of that fit my needs.
After a while of searching , I read a post in a forum that mentioned a implementation of a sliding text view with a Custom NSView and Core Animation. Unfortunately no sample code was given. Due to I don’t use Core Animation before, I decided to dive a little bit into Core Animation.

The plan was:

1. Create a NSView subclass
2. Say the NSView that he needs a layer.
Core Animation is layer based, it’s like the view hierarchy with NSView and subviews. Basically a NSView don’t have a layer attached, you must explicitly say that he needs a layer in the Interface Builder. You see the necessary setting in the following screenshot:

3. Create a CAScrollLayer and set it as the layer of the NSView subclass
4. Add a CATextLayer to our CAScrollLayer
5. Attach a animation to the CATextLayer that scrolls the text within the CAScrollLayer.
In detail, it changes the position property of the CATextLayer that results in a sliding effect.

The result code is at the following:

Header file:

#import <Cocoa/Cocoa.h>

@class CATextLayer;
@class CAScrollLayer;

@interface CustomTextScrollView : NSView {
   
    CAScrollLayer *scrollLayer;
    CATextLayer *textLayer;
   
    float fontSize;
}

- (void)setText:(NSString *)text;

@end

Implementation file:

#import "CustomTextScrollView.h"
#import <Quartz/Quartz.h>

// Helper class to set different colors for foreground or backgrounds
@interface CustomTextScrollView(Color)
- (CGColorRef)black;
- (CGColorRef)white;
- (CGColorRef)blue;
- (CGColorRef)red;
- (CGColorRef)green;
@end

@implementation CustomTextScrollView

- (id)initWithFrame:(NSRect)frame{
    if (self = [super initWithFrame:frame]) {
        fontSize = 14;
       
        // ScrollLayer
        scrollLayer = [CAScrollLayer layer];
        scrollLayer.frame = NSRectToCGRect([self bounds]);
       
        // TextLayer
        textLayer = [CATextLayer layer];
        textLayer.foregroundColor = [self black];
        textLayer.fontSize = fontSize;
       
        // Set textLayer as sublayer of the scrollLayer
        [scrollLayer addSublayer:textLayer];
       
        [self setLayer:scrollLayer];
       
    }
    return self;
}

- (void)setText:(NSString *)text {
    [textLayer removeFromSuperlayer];
   
    textLayer.string = text;
   
    //  Get the width of the text and set it as the new width of the textLayer
    NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:[NSFont fontWithName:@"Helvetica" size:textLayer.fontSize], NSFontAttributeName, nil];
    float textWidth = [text sizeWithAttributes:attributes].width;
    NSRect textRect = NSMakeRect(0.0, 0.0, textWidth, scrollLayer.frame.size.height);
    textLayer.frame = NSRectToCGRect(textRect);
   
    // Animate only if text is longer than the view
    if (self.frame.size.width < textRect.size.width) {
        [self addAnimation];
    } else {
        // Place text in the middle of the textlayer
        float newX = ([self frame].size.width - textRect.size.width) / 2;
        NSRect newTextRect = NSMakeRect(newX, 0, textLayer.frame.size.width, textLayer.frame.size.height);
        textLayer.frame = NSRectToCGRect(newTextRect);
    }
   
    [scrollLayer addSublayer:textLayer];
}

- (void)addAnimation {
    // Prepare the animation from the current position to the new position
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
    animation.autoreverses = YES;
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    animation.duration = 2.5;
    animation.repeatCount = HUGE_VALF;
   
    NSPoint from = [textLayer position];
    from.x += 10;
    animation.fromValue = [NSValue valueWithPoint:from];
   
    NSPoint to = [scrollLayer position];
    to.x -= (textLayer.frame.size.width - textLayer.position.x - (self.frame.size.width/2) + 10);
    animation.toValue = [NSValue valueWithPoint:to];
   
    // Add the animation, overriding the implicit animation.
    [textLayer addAnimation:animation forKey:@"position"];
}


- (void)drawRect:(NSRect)dirtyRect {
    // Drawing code here.
}

- (void)dealloc {
    [super dealloc];
}

@end

@implementation CustomTextScrollView(Color)

- (CGColorSpaceRef)genericRGBSpace {
    static CGColorSpaceRef space = NULL;
    if(NULL == space) {
        space = CGColorSpaceCreateWithName (kCGColorSpaceGenericRGB);
    }
    return space;
}

- (CGColorRef)black {
    static CGColorRef black = NULL;
    if(black == NULL) {
        CGFloat values[4] = {0.0, 0.0, 0.0, 1.0};
        black = CGColorCreate([self genericRGBSpace], values);
    }
    return black;
}

- (CGColorRef)white{
    static CGColorRef white = NULL;
    if(white == NULL) {
        CGFloat values[4] = {1.0, 1.0, 1.0, 1.0};
        white = CGColorCreate([self genericRGBSpace], values);
    }
    return white;
}

- (CGColorRef)blue {
    static CGColorRef blue = NULL;
    if(blue == NULL) {
        CGFloat values[4] = {0.0, 0.0, 1.0, 1.0};
        blue = CGColorCreate([self genericRGBSpace], values);
    }
    return blue;
}

- (CGColorRef)red {
    static CGColorRef red = NULL;
    if(red == NULL) {
        CGFloat values[4] = {1.0, 0.0, 0.0, 1.0};
        red = CGColorCreate([self genericRGBSpace], values);
    }
    return red;
}

- (CGColorRef)green {
    static CGColorRef green = NULL;
    if(green == NULL) {
        CGFloat values[4] = {0.0, 1.0, 0.0, 1.0};
        green = CGColorCreate([self genericRGBSpace], values);
    }
    return green;
}

@end

You will find a sample Xcode project on my github-profile.

Linking to the Google Data APIs Objective-C Client Library in iPhone SDK 4.0

In the last weekend I tried to dive a little bit into the Google Data APIs Objective-C Client Library. Unfortunately it wasn’t so easy to integrate the Library into my iPhone project as I thought at the beginning.

If you would like to integrate the Google Data APIs Library in one of your iPhone Projects, I wrote the necessary steps, down which you can read at the following:

First of all we have to add the necessary frameworks to the iPhone Project.
This are the Security.framework and the SystemConfiguration.framework. For each of the frameworks we have to do the following:
We make a right click on the “Frameworks” folder in the “Group & Files” list and choose the “Add->Existing Frameworks…” menu item.

We scroll to the respective framework, click on it, and click the “Add” button.

Next, we download the source of the Google Data APIs Objective-C Client Library from the URL: http://code.google.com/p/gdata-objectivec-client and make some necessary preparations.
After unzipping the archive we open the GData.xcodeproj file in the “Source” directory.

After Xcode opened the GData.xcodeproj file we click on the left triangle besides the “Targets” entry. Then we make a double click on the GDataTouchStaticLib and substitute the Base SDK entry from “iPhone Device 3.0″ to “iPhone Device 4.0″.

At the end we have to open the project settings for the GData.xcodeproj file (Project -> Edit Project Settings) and delete all entries in “Other warning flags”.

Back to the iPhone Project.
The GData library project includes a target for building a static library for iPhone and iPod Touch apps; this avoids dragging individual library source files into the iPhone application’s project. To build the iPhone poject with the static library we have to make a cross project reference.
There are two ways, choose on of it:

  • drag the GData.xcodeproj file itself from the Finder into “Groups & Files” in the iPhone project
  • add the GData.xcodeproj file with “Project->Add to Project…” to the iPhone project

In the next step, we add the GDataTouchStaticLib target as a dependency for building the iPhone project: We have to do a click on the triangle besides the Target entry, a right mouse click on the Target in the targets list and a click on the “Get info” menu item.

Now you switch to the “General” pane on the top of the target editor. To add a target dependency, click the plus-sign button. The list of targets shown includes all the other targets in the current project, as well as the targets in any referenced projects. Due to we have the GData.xcodeproj as a cross reference we see the GDataTouchStaticLib in the list of targets. Now we click on the GDataTouchStaticLib and “Add Target” Button to add it as a target dependency. After that we close the target editor window.

The next step is to drag the static library target (libGDataTouchStaticLibrary) from under the GData.xcodeproj cross-project reference in our iPhone project to the target’s “Link Binary With Libraries” build phase from our iPhone project. You will see the “Link Binary With Libraries” build phase if you click on the triangle besides you Target.

Next we have to add some “Other Linker Flags” to the iPhone project preferences. In Xcode, double-click the target’s name under “Targets” in the project window. Choose the “Build” pane from the ensuing “Info” window. Scroll down to the “Other Linker Flags” build setting under the Linking collection and open it with a double click. Add “-ObjC” in line 1 and “-lxml2″ in line 2 to the table view.

After that, we will have problems to build the Project, because Xcode can’t find the lxml library. To solve this problem we add to the “Header Search Paths” build setting the entry: /usr/include/libxml2

Now we have to build the iPhone project to create header files of the static library. Click (Build->build). After the build have been finished, the static library build creates the necessary directory of header files (in its build products directory) that should be dragged into the iPhone project.

So go to the the GData Project Folder and change the folder to “Source -> build -> Debug-iphonesimulator” and you will see a directory called “Headers”. We drag the hole directory to our iPhone project.

Thats all, with the static library linked into your project, refer directly to the headers by omitting the framework name, like

#import "GData.h"

in your source files.

Further informations you will find at the following links:

ImageStoreMac a image cache library for the Mac

I’ve finished my exams last week and as I wrote in the last post, I started to program on ReadNow again.
I’m currently implementing some feature request from users of ReadNow. This contains the display of favicons and growl support. The favicon integration is a bit tricky, because I don’t have so many experiences with image handling and I have also different ideas and approaches for the implementation. But all of these ideas had one component that is necessary: an image cache. Fortunately I looked on github and found a library with the name ImageStore from psychs, a developer from Japan that works on Echofon for Mac or LimeChat for Mac. Unfortunately the library is only for iPhone development and so I decided to make it Mac compatible and change it also a little bit for my purposes.
The result is also on github and you will found it on my github profile at: http://github.com/maicki with the name: ImageStoreMac.

Some details of ImageStoreMac:
* What is ImageStore

ImageStore is a library for the Mac to download images in background automatically and cache it.
The sample project includes also a HttpClient, I would hope it will help you.

* How to use
See the sample project that downloads some favicons and display it in a NSTabelView.

* The Author
Mac Version:
Michael Schneider
http://mischneider.net/

iPhone Version:
Satoshi Nakagawa
http://limechat.net/psychs/
#limechat on irc.freenode.net

* License
The New BSD License

Current Situation

Today I will post a little update to my current situation and the state of ReadNow. Unfortuantely I must write important exams in the next weeks and so I don’t have much time to program on ReadNow currently. A soon as I have finished my exams I will start to improve ReadNow and implement new features.

ReadNow – A Mac application for Read It Later

I’ve started Mac Programming a week ago and I searched for a little project. Due to Read It Later is one of my favorite services, I thought, maybe it would be nice, if I have a little mac application for it. So the Idea of “ReadNow” was born. ReadNow is a little application that sits on the menubar and uses the Read It Later API to communicate to Read It Later.

You will find additional informations about it at my projects site.