Full offline. Adding feeds table and caching of feed list by username. Also optimizing unread story fetching by placing all db calls in a background thread.

This commit is contained in:
Samuel Clay 2013-06-20 19:25:57 -07:00
parent bf190960bc
commit d2b3db972d
7 changed files with 124 additions and 51 deletions

View file

@ -622,19 +622,23 @@
[appDelegate.storyPageControl resizeScrollView];
[appDelegate.storyPageControl setStoryFromScroll:YES];
[appDelegate.storyPageControl advanceToNextUnread];
[appDelegate.database inTransaction:^(FMDatabase *db, BOOL *rollback) {
for (NSDictionary *story in confirmedNewStories) {
[db executeUpdate:@"INSERT into stories"
"(story_feed_id, story_hash, story_timestamp, story_json) VALUES "
"(?, ?, ?, ?)",
[story objectForKey:@"story_feed_id"],
[story objectForKey:@"story_hash"],
[story objectForKey:@"story_timestamp"],
[story JSONRepresentation]
];
}
// NSLog(@"Inserting %d stories: %@", [confirmedNewStories count], [db lastErrorMessage]);
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
(unsigned long)NULL), ^(void) {
[appDelegate.database inTransaction:^(FMDatabase *db, BOOL *rollback) {
for (NSDictionary *story in confirmedNewStories) {
[db executeUpdate:@"INSERT into stories"
"(story_feed_id, story_hash, story_timestamp, story_json) VALUES "
"(?, ?, ?, ?)",
[story objectForKey:@"story_feed_id"],
[story objectForKey:@"story_hash"],
[story objectForKey:@"story_timestamp"],
[story JSONRepresentation]
];
}
// NSLog(@"Inserting %d stories: %@", [confirmedNewStories count], [db lastErrorMessage]);
}];
});
[self.notifier hide];
}

View file

@ -180,7 +180,7 @@
MBProgressHUD *HUD = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
HUD.labelText = @"Authenticating";
NSString *urlString = [NSString stringWithFormat:@"https://%@/api/login",
NSString *urlString = [NSString stringWithFormat:@"%@/api/login",
NEWSBLUR_URL];
NSURL *url = [NSURL URLWithString:urlString];
[[NSHTTPCookieStorage sharedHTTPCookieStorage]

View file

@ -133,7 +133,6 @@
[__accessoryView setFrame:CGRectMake((32 - __accessoryView.frame.size.width) / 2 + offset, ((self.frame.size.height -__accessoryView.frame.size.height)/2)+2, __accessoryView.frame.size.width, __accessoryView.frame.size.height)];
[self addSubview:__accessoryView];
NSLog(@"Accessory view: %@", __accessoryView);
if (self.style == NBSyncingStyle || self.style == NBSyncingProgressStyle) {
[_txtLabel setFrame:CGRectMake(34, (NOTIFIER_HEIGHT / 2) - 8, self.frame.size.width - 32, 20)];
} else {
@ -177,7 +176,7 @@
- (void)setView:(UIView *)view {
_view = view;
NSLog(@"Notifier view: %@ / %@", NSStringFromCGRect(view.bounds), NSStringFromCGPoint(self.offset));
if (self.showing) {
self.frame = CGRectMake(0, view.bounds.size.height - self.offset.y - self.frame.size.height, view.bounds.size.width, NOTIFIER_HEIGHT);
} else {

View file

@ -45,7 +45,7 @@
@implementation NewsBlurAppDelegate
#define CURRENT_DB_VERSION 8
#define CURRENT_DB_VERSION 9
#define IS_IPHONE_5 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )
@synthesize window;
@ -2042,6 +2042,15 @@
NSLog(@"Dropped db: %@", [db lastErrorMessage]);
sqlite3_exec(db.sqliteHandle, [[NSString stringWithFormat:@"PRAGMA user_version = %d", CURRENT_DB_VERSION] UTF8String], NULL, NULL, NULL);
}
NSString *createFeedsTable = [NSString stringWithFormat:@"create table if not exists feeds "
"("
" username varchar(36),"
" download_date date,"
" feeds_json text,"
" UNIQUE(username) ON CONFLICT REPLACE"
")"];
[db executeUpdate:createFeedsTable];
NSString *createStoryTable = [NSString stringWithFormat:@"create table if not exists stories "
"("
" story_feed_id number,"
@ -2108,11 +2117,13 @@
JSONObjectWithData:responseData
options:kNilOptions
error:&error];
__block __typeof__(self) _self = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
(unsigned long)NULL), ^(void) {
[self.database inTransaction:^(FMDatabase *db, BOOL *rollback) {
[_self.database inTransaction:^(FMDatabase *db, BOOL *rollback) {
[db executeUpdate:@"DROP TABLE unread_hashes"];
[self setupDatabase:db];
[_self setupDatabase:db];
NSDictionary *hashes = [results objectForKey:@"unread_feed_story_hashes"];
for (NSString *feed in [hashes allKeys]) {
NSArray *story_hashes = [hashes objectForKey:feed];
@ -2128,10 +2139,10 @@
}
}];
self.totalUnfetchedStoryCount = 0;
self.remainingUnfetchedStoryCount = 0;
self.latestFetchedStoryDate = 0;
[self fetchAllUnreadStories];
_self.totalUnfetchedStoryCount = 0;
_self.remainingUnfetchedStoryCount = 0;
_self.latestFetchedStoryDate = 0;
[_self fetchAllUnreadStories];
});
}
@ -2210,32 +2221,36 @@
options:kNilOptions
error:&error];
__block BOOL anySuccess = NO;
__block __typeof__(self) _self = self;
[self.database inTransaction:^(FMDatabase *db, BOOL *rollback) {
for (NSDictionary *story in [results objectForKey:@"stories"]) {
BOOL inserted = [db executeUpdate:@"INSERT into stories"
"(story_feed_id, story_hash, story_timestamp, story_json) VALUES "
"(?, ?, ?, ?)",
[story objectForKey:@"story_feed_id"],
[story objectForKey:@"story_hash"],
[story objectForKey:@"story_timestamp"],
[story JSONRepresentation]
];
if (!anySuccess && inserted) anySuccess = YES;
}
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
(unsigned long)NULL), ^(void) {
[_self.database inTransaction:^(FMDatabase *db, BOOL *rollback) {
for (NSDictionary *story in [results objectForKey:@"stories"]) {
BOOL inserted = [db executeUpdate:@"INSERT into stories"
"(story_feed_id, story_hash, story_timestamp, story_json) VALUES "
"(?, ?, ?, ?)",
[story objectForKey:@"story_feed_id"],
[story objectForKey:@"story_hash"],
[story objectForKey:@"story_timestamp"],
[story JSONRepresentation]
];
if (!anySuccess && inserted) anySuccess = YES;
}
if (anySuccess) {
_self.latestFetchedStoryDate = [[[[results objectForKey:@"stories"] lastObject]
objectForKey:@"story_timestamp"] intValue];
}
}];
if (anySuccess) {
self.latestFetchedStoryDate = [[[[results objectForKey:@"stories"] lastObject]
objectForKey:@"story_timestamp"] intValue];
[_self fetchAllUnreadStories];
} else {
dispatch_async(dispatch_get_main_queue(), ^{
[_self.feedsViewController hideNotifier];
});
}
}];
if (anySuccess) {
[self fetchAllUnreadStories];
} else {
dispatch_async(dispatch_get_main_queue(), ^{
[self.feedsViewController hideNotifier];
});
}
});
}
- (void)flushQueuedReadStories:(BOOL)forceCheck withCallback:(void(^)())callback {

View file

@ -76,6 +76,7 @@ UIPopoverControllerDelegate> {
- (void)fetchFeedList:(BOOL)showLoader;
- (void)finishedWithError:(ASIHTTPRequest *)request;
- (void)finishLoadingFeedList:(ASIHTTPRequest *)request;
- (void)finishLoadingFeedListWithDict:(NSDictionary *)results;
- (void)finishRefreshingFeedList:(ASIHTTPRequest *)request;
- (void)setUserAvatarLayout:(UIInterfaceOrientation)orientation;
- (void)didSelectSectionHeader:(UIButton *)button;

View file

@ -22,10 +22,13 @@
#import "PullToRefreshView.h"
#import "MBProgressHUD.h"
#import "Base64.h"
#import "JSON.h"
#import "NBNotifier.h"
#import "Utilities.h"
#import "UIBarButtonItem+WEPopover.h"
#import "AddSiteViewController.h"
#import "FMDatabase.h"
#import "FMDatabaseAdditions.h"
#define kPhoneTableViewRowHeight 31;
#define kTableViewRowHeight 31;
@ -478,8 +481,28 @@ static const CGFloat kFolderTitleHeight = 28;
NSError *error;
NSDictionary *results = [NSJSONSerialization
JSONObjectWithData:responseData
options:kNilOptions
options:kNilOptions
error:&error];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
(unsigned long)NULL), ^(void) {
[appDelegate.database inTransaction:^(FMDatabase *db, BOOL *rollback) {
[db executeUpdate:@"DELETE FROM feeds WHERE username = ?", appDelegate.activeUsername];
[db executeUpdate:@"INSERT into feeds"
"(username, download_date, feeds_json) VALUES "
"(?, ?, ?)",
appDelegate.activeUsername,
[NSDate date],
[results JSONRepresentation]
];
}];
});
[self finishLoadingFeedListWithDict:results];
}
- (void)finishLoadingFeedListWithDict:(NSDictionary *)results {
NSUserDefaults *userPreferences = [NSUserDefaults standardUserDefaults];
appDelegate.savedStoriesCount = [[results objectForKey:@"starred_count"] intValue];
// NSLog(@"results are %@", results);
@ -489,6 +512,8 @@ static const CGFloat kFolderTitleHeight = 28;
[self loadFavicons];
appDelegate.activeUsername = [results objectForKey:@"user"];
[userPreferences setObject:appDelegate.activeUsername forKey:@"active_username"];
[userPreferences synchronize];
// // set title only if on currestont controller
// if (appDelegate.feedsViewController.view.window && [results objectForKey:@"user"]) {
@ -717,7 +742,35 @@ static const CGFloat kFolderTitleHeight = 28;
- (void)loadOfflineFeeds {
__block __typeof__(self) _self = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
(unsigned long)NULL), ^(void) {
[appDelegate.database inDatabase:^(FMDatabase *db) {
NSDictionary *results;
NSUserDefaults *userPreferences = [NSUserDefaults standardUserDefaults];
if (!appDelegate.activeUsername) {
appDelegate.activeUsername = [userPreferences stringForKey:@"active_username"];
if (!appDelegate.activeUsername) return;
}
FMResultSet *cursor = [db executeQuery:@"SELECT * FROM feeds WHERE username = ? LIMIT 1",
appDelegate.activeUsername];
while ([cursor next]) {
NSDictionary *feedsCache = [cursor resultDictionary];
results = [NSJSONSerialization
JSONObjectWithData:[[feedsCache objectForKey:@"feeds_json"]
dataUsingEncoding:NSUTF8StringEncoding]
options:nil error:nil];
break;
}
dispatch_async(dispatch_get_main_queue(), ^{
[_self finishLoadingFeedListWithDict:results];
});
}];
});
}
- (void)showUserProfile {

View file

@ -13,9 +13,10 @@
// #define BACKGROUND_REFRESH_SECONDS -5
#define BACKGROUND_REFRESH_SECONDS -10*60
// #define NEWSBLUR_URL [NSString stringWithFormat:@"nb.local.com"]
#define NEWSBLUR_URL [NSString stringWithFormat:@"https://www.newsblur.com"]
#define NEWSBLUR_HOST [NSString stringWithFormat:@"www.newsblur.com"]
#define NEWSBLUR_URL [NSString stringWithFormat:@"http://nb.local.com"]
#define NEWSBLUR_HOST [NSString stringWithFormat:@"nb.local.com"]
// #define NEWSBLUR_URL [NSString stringWithFormat:@"https://www.newsblur.com"]
// #define NEWSBLUR_HOST [NSString stringWithFormat:@"www.newsblur.com"]
#define NEWSBLUR_LINK_COLOR 0x405BA8
#define NEWSBLUR_HIGHLIGHT_COLOR 0xd2e6fd