Skip to content

Commit

Permalink
Native App-to-Web Browser Handoff.
Browse files Browse the repository at this point in the history
For thread lists, posts, and PMs.
  • Loading branch information
nolanw committed Oct 22, 2014
1 parent 043f3e8 commit a040e5c
Show file tree
Hide file tree
Showing 9 changed files with 166 additions and 1 deletion.
11 changes: 11 additions & 0 deletions Source/Main/AwfulAppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#import "AwfulWaffleimagesURLProtocol.h"
#import <Crashlytics/Crashlytics.h>
#import <GRMustache/GRMustache.h>
#import "Handoff.h"
#import <Smilies/Smilies.h>
#import "Awful-Swift.h"

Expand Down Expand Up @@ -371,4 +372,14 @@ - (BOOL)application:(UIApplication *)application
return [self openAwfulURL:URL];
}

#pragma mark Handoff

- (void)application:(UIApplication *)application didUpdateUserActivity:(NSUserActivity *)userActivity
{
// Bit of future-proofing.
[userActivity addUserInfoEntriesFromDictionary:@{HandoffInfoVersionKey: @(HandoffVersion)}];
}

static const NSInteger HandoffVersion = 1;

@end
21 changes: 21 additions & 0 deletions Source/Main/Handoff.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Handoff.h
//
// Copyright 2014 Awful Contributors. CC BY-NC-SA 3.0 US https://github.com/Awful/Awful.app

#import <Foundation/Foundation.h>

extern NSString * const HandoffInfoVersionKey;

extern NSString * const HandoffActivityTypeBrowsingPosts;
extern NSString * const HandoffInfoThreadIDKey;
extern NSString * const HandoffInfoPostIDKey;
extern NSString * const HandoffInfoFilteredThreadUserIDKey;

extern NSString * const HandoffActivityTypeListingThreads;
extern NSString * const HandoffInfoForumIDKey;
extern NSString * const HandoffInfoBookmarksKey;

extern NSString * const HandoffActivityTypeReadingMessage;
extern NSString * const HandoffInfoMessageIDKey;

extern NSString * const HandoffInfoPageKey;
21 changes: 21 additions & 0 deletions Source/Main/Handoff.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Handoff.m
//
// Copyright 2014 Awful Contributors. CC BY-NC-SA 3.0 US https://github.com/Awful/Awful.app

#import "Handoff.h"

NSString * const HandoffInfoVersionKey = @"version";

NSString * const HandoffActivityTypeBrowsingPosts = @"com.awfulapp.Awful.activity.browsing-posts";
NSString * const HandoffInfoThreadIDKey = @"threadID";
NSString * const HandoffInfoPostIDKey = @"postID";
NSString * const HandoffInfoFilteredThreadUserIDKey = @"filteredUserID";

NSString * const HandoffActivityTypeListingThreads = @"com.awfulapp.Awful.activity.listing-threads";
NSString * const HandoffInfoForumIDKey = @"forumID";
NSString * const HandoffInfoBookmarksKey = @"bookmarks";

NSString * const HandoffActivityTypeReadingMessage = @"com.awfulapp.Awful.activity.reading-message";
NSString * const HandoffInfoMessageIDKey = @"messageID";

NSString * const HandoffInfoPageKey = @"page";
45 changes: 44 additions & 1 deletion Source/Posts/PostsPageViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
#import "AwfulWebViewNetworkActivityIndicatorManager.h"
#import "BrowserViewController.h"
#import <Crashlytics/Crashlytics.h>
#import <GRMustache.h>
#import <GRMustache/GRMustache.h>
#import "Handoff.h"
#import "MessageComposeViewController.h"
#import <MRProgress/MRProgressOverlayView.h>
#import "PostComposeViewController.h"
Expand Down Expand Up @@ -150,6 +151,8 @@ - (void)loadPage:(NSInteger)page updatingCache:(BOOL)updateCache

[self updateUserInterface];

[self configureUserActivityIfPossible];

if (!updateCache) {
[self clearLoadingMessage];
return;
Expand Down Expand Up @@ -194,6 +197,8 @@ - (void)loadPage:(NSInteger)page updatingCache:(BOOL)updateCache

if (error) return;

[self configureUserActivityIfPossible];

if (self.hiddenPosts == 0 && firstUnreadPost != NSNotFound) {
self.hiddenPosts = firstUnreadPost;
}
Expand Down Expand Up @@ -1008,6 +1013,44 @@ - (void)viewDidAppear:(BOOL)animated
__typeof__(self) self = weakSelf;
[self loadNextPageOrRefresh];
} position:SVPullToRefreshPositionBottom];

[self configureUserActivityIfPossible];
}

- (void)configureUserActivityIfPossible
{
if (self.page >= 1) {
self.userActivity = [[NSUserActivity alloc] initWithActivityType:HandoffActivityTypeBrowsingPosts];
self.userActivity.needsSave = YES;
} else {
self.userActivity = nil;
}
}

- (void)updateUserActivityState:(NSUserActivity *)activity
{
activity.title = self.thread.title;
[activity addUserInfoEntriesFromDictionary:@{HandoffInfoThreadIDKey: self.thread.threadID,
HandoffInfoPageKey: @(self.page)}];
if (self.author) {
[activity addUserInfoEntriesFromDictionary:@{HandoffInfoFilteredThreadUserIDKey: self.author.userID}];
}

NSMutableString *relativeString = [NSMutableString new];
[relativeString appendFormat:@"/showthread.php?threadid=%@&perpage=40", self.thread.threadID];
if (self.page > 1) {
[relativeString appendFormat:@"&pagenumber=%@", @(self.page)];
}
if (self.author) {
[relativeString appendFormat:@"&userid=%@", self.author.userID];
}
activity.webpageURL = [NSURL URLWithString:relativeString relativeToURL:[AwfulForumsClient client].baseURL];
}

- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
self.userActivity = nil;
}

#pragma mark - AwfulComposeTextViewControllerDelegate
Expand Down
24 changes: 24 additions & 0 deletions Source/Private Messages/MessageViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#import "AwfulWebViewNetworkActivityIndicatorManager.h"
#import "BrowserViewController.h"
#import <GRMustache/GRMustache.h>
#import "Handoff.h"
#import "MessageComposeViewController.h"
#import "RapSheetViewController.h"
#import <TUSafariActivity/TUSafariActivity.h>
Expand Down Expand Up @@ -319,6 +320,7 @@ - (void)viewDidLoad
[self renderMessage];
[self.loadingView removeFromSuperview];
self.loadingView = nil;
self.userActivity.needsSave = YES;
}];
} else {
[self renderMessage];
Expand All @@ -337,6 +339,28 @@ - (void)themeDidChange
self.loadingView.tintColor = theme[@"backgroundColor"];
}

- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.userActivity = [[NSUserActivity alloc] initWithActivityType:HandoffActivityTypeReadingMessage];
self.userActivity.needsSave = YES;
}

- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
self.userActivity = nil;
}

- (void)updateUserActivityState:(NSUserActivity *)activity
{
[activity addUserInfoEntriesFromDictionary:@{HandoffInfoMessageIDKey: self.privateMessage.messageID}];
NSString *subject = self.privateMessage.subject;
activity.title = subject.length > 0 ? subject : @"Private Message";
activity.webpageURL = [NSURL URLWithString:[NSString stringWithFormat:@"/private.php?action=show&privatemessageid=%@", self.privateMessage.messageID]
relativeToURL:[AwfulForumsClient client].baseURL];
}

#pragma mark - UIWebViewDelegate

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
Expand Down
16 changes: 16 additions & 0 deletions Source/Threads/BookmarkedThreadListViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#import "AwfulModels.h"
#import "AwfulRefreshMinder.h"
#import "AwfulSettings.h"
#import "Handoff.h"
#import <SVPullToRefresh/SVPullToRefresh.h>
#import "Awful-Swift.h"

Expand Down Expand Up @@ -84,6 +85,8 @@ - (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self refreshIfNecessary];
self.userActivity = [[NSUserActivity alloc] initWithActivityType:HandoffActivityTypeListingThreads];
self.userActivity.needsSave = YES;
}

- (void)refreshIfNecessary
Expand Down Expand Up @@ -118,6 +121,19 @@ - (void)loadPage:(NSInteger)page
}];
}

- (void)updateUserActivityState:(NSUserActivity *)activity
{
activity.title = @"Bookmarked Threads";
[activity addUserInfoEntriesFromDictionary:@{HandoffInfoBookmarksKey: @YES}];
activity.webpageURL = [NSURL URLWithString:@"/bookmarkthreads.php" relativeToURL:[AwfulForumsClient client].baseURL];
}

- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
self.userActivity = nil;
}

#pragma mark - AwfulFetchedResultsControllerDataSourceDelegate

- (BOOL)canDeleteObject:(id)object atIndexPath:(NSIndexPath *)indexPath
Expand Down
17 changes: 17 additions & 0 deletions Source/Threads/ThreadListViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#import "AwfulSettings.h"
#import "AwfulThreadTagLoader.h"
#import "AwfulThreadTagPickerController.h"
#import "Handoff.h"
#import "PostsPageViewController.h"
#import <SVPullToRefresh/SVPullToRefresh.h>
#import "Awful-Swift.h"
Expand Down Expand Up @@ -166,6 +167,8 @@ - (void)viewDidAppear:(BOOL)animated
NSFetchedResultsController *fetchedResultsController = self.threadDataSource.fetchedResultsController;
self.tableView.showsInfiniteScrolling = fetchedResultsController.fetchedObjects.count > 0;
[self refreshIfNecessary];
self.userActivity = [[NSUserActivity alloc] initWithActivityType:HandoffActivityTypeListingThreads];
self.userActivity.needsSave = YES;
}

- (void)refreshIfNecessary
Expand Down Expand Up @@ -211,6 +214,20 @@ - (void)loadPage:(NSInteger)page
}];
}

- (void)updateUserActivityState:(NSUserActivity *)activity
{
activity.title = self.forum.name;
[activity addUserInfoEntriesFromDictionary:@{HandoffInfoForumIDKey: self.forum.forumID}];
activity.webpageURL = [NSURL URLWithString:[NSString stringWithFormat:@"/forumdisplay.php?forumid=%@", self.forum.forumID]
relativeToURL:[AwfulForumsClient client].baseURL];
}

- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
self.userActivity = nil;
}

#pragma mark - AwfulThreadTableViewController

- (AwfulTheme *)theme
Expand Down
6 changes: 6 additions & 0 deletions Xcode/Awful.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
1C270ABE16E0773300883DAA /* AwfulComposeField.m in Sources */ = {isa = PBXBuildFile; fileRef = 1C270ABD16E0773300883DAA /* AwfulComposeField.m */; };
1C28B3501729DDDA00254EE7 /* AwfulIconActionItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 1C28B34F1729DDDA00254EE7 /* AwfulIconActionItem.m */; };
1C28B3591729F38400254EE7 /* AwfulIconActionCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 1C28B3581729F38400254EE7 /* AwfulIconActionCell.m */; };
1C2D20C419F74FC800F64577 /* Handoff.m in Sources */ = {isa = PBXBuildFile; fileRef = 1C2D20C319F74FC800F64577 /* Handoff.m */; };
1C3447C9174D728B007377C5 /* AwfulThreadTagView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1C3447C7174D7284007377C5 /* AwfulThreadTagView.m */; };
1C3447D2174D9B01007377C5 /* AwfulThreadTagButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 1C3447D1174D9B01007377C5 /* AwfulThreadTagButton.m */; };
1C3447DD175D2D5E007377C5 /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 1C3447DC175D2D5E007377C5 /* Settings.bundle */; };
Expand Down Expand Up @@ -443,6 +444,8 @@
1C28B34F1729DDDA00254EE7 /* AwfulIconActionItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = AwfulIconActionItem.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
1C28B3571729F38400254EE7 /* AwfulIconActionCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AwfulIconActionCell.h; sourceTree = "<group>"; };
1C28B3581729F38400254EE7 /* AwfulIconActionCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AwfulIconActionCell.m; sourceTree = "<group>"; };
1C2D20C219F74FC800F64577 /* Handoff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Handoff.h; sourceTree = "<group>"; };
1C2D20C319F74FC800F64577 /* Handoff.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Handoff.m; sourceTree = "<group>"; };
1C3447C6174D7284007377C5 /* AwfulThreadTagView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AwfulThreadTagView.h; sourceTree = "<group>"; };
1C3447C7174D7284007377C5 /* AwfulThreadTagView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AwfulThreadTagView.m; sourceTree = "<group>"; };
1C3447D0174D9B01007377C5 /* AwfulThreadTagButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AwfulThreadTagButton.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -924,6 +927,8 @@
1CBE1B1119CAAFA200510187 /* AwfulSplitViewController.swift */,
1C89A79218AF4DA500D75854 /* EmptyViewController.h */,
1C89A79318AF4DA500D75854 /* EmptyViewController.m */,
1C2D20C219F74FC800F64577 /* Handoff.h */,
1C2D20C319F74FC800F64577 /* Handoff.m */,
1CDD0A4619B7D89B009811C4 /* LaunchScreen.storyboard */,
1190F7F213BE4EDA00B9D271 /* main.m */,
1190F7F113BE4EDA00B9D271 /* Prefix.pch */,
Expand Down Expand Up @@ -2368,6 +2373,7 @@
1C8D116319B3F69D005D46CB /* ThreadCell.swift in Sources */,
1C9A746118EA62F900093E33 /* AwfulUnreadPrivateMessageCountScraper.m in Sources */,
1CE2D9D9166ABD0D0024AC1C /* AwfulNavigationBar.m in Sources */,
1C2D20C419F74FC800F64577 /* Handoff.m in Sources */,
1CE2D9DC166ABD0D0024AC1C /* NSFileManager+UserDirectories.m in Sources */,
1CD82F2D19428D0900B0C5BD /* AwfulImageURLProtocol.m in Sources */,
1CBE1B1219CAAFA200510187 /* AwfulSplitViewController.swift in Sources */,
Expand Down
6 changes: 6 additions & 0 deletions Xcode/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@
<string>4db466addcb5cfc</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSUserActivityTypes</key>
<array>
<string>com.awfulapp.Awful.activity.browsing-posts</string>
<string>com.awfulapp.Awful.activity.listing-threads</string>
<string>com.awfulapp.Awful.activity.reading-message</string>
</array>
<key>UIInterfaceOrientation</key>
<string>UIInterfaceOrientationPortrait</string>
<key>UILaunchStoryboardName</key>
Expand Down

0 comments on commit a040e5c

Please sign in to comment.