hatena / hatena-bookmark-ios-sdk Goto Github PK
View Code? Open in Web Editor NEWThis library is deprecated.
License: MIT License
This library is deprecated.
License: MIT License
という時に、最後に認証した端末以外で内部API通信エラー(HTTP 401)が発生し、はてなブックマークへの登録操作ができなくなります。
ユーザーサイドからはエラーアラートが出るだけです。
たとえば1人のはてなユーザーがiPhone、iPad双方から同じiOSアプリを使うような時発生します。
この時サーバーからは以下の"token_rejected"レスポンスが返ってきていました。
(lldb) po [operation.response allHeaderFields]
{
Connection = "keep-alive";
"Content-Encoding" = gzip;
"Content-Length" = 48;
"Content-Type" = "text/plain; charset=utf-8";
Date = "Tue, 27 Aug 2013 09:03:10 GMT";
Server = nginx;
... 中略 ...
Vary = "Accept-Encoding,User-Agent";
"Www-Authenticate" = "OAuth realm=\"\", oauth_problem=\"token_rejected\"";
"X-Content-Type-Options" = nosniff;
"X-Framework" = "Ridge/0.11";
"X-Ridge-Dispatch" = "Hatena::Bookmark::Engine::Api::V1::My#default";
"X-Runtime" = 18ms;
}
SDK を組み込んだアプリ (HBFav2) のユーザーから報告が上がっているのですが、表題の現象が起こるようです。
ひとによって発生頻度が違っていて
とがいるようです。
issue の中でもコメントしていますが、はてなの認証は、当方のアプリでは HTBHatenaBookmarkViewController.alloc.init でコントローラを起動して、以降の処理は完全に SDK 側に任せているため、おそらくですが、SDK もしくはサーバーサイドに原因があるのではないか、と思っています。
ただし、当方が利用しているのが RubyMotion なので、(可能性は低いものの) Objective-C で書いた場合との互換性の部分に差があって何か問題が起こっていることも否定はできません。
ブックマークするビューで「追加」を押したときに、閉じていく瞬間に「直前の」ソーシャルボタンのON/OFF状況が見えることがあります。
再現例
このようにすると手元では再現します。
毎回「あれっ? 共有にしたままだっけ」と思ってどきっとし、Twitterに流れているか確認することがあるので、できれば正常な表示になるととてもありがたく存じます。
すみません。下部の本投稿はこちらの思い違いでした。
authorizeWithSuccessはそのままで、追加するアプリケーション側にread_privateが必要ということですね。
失礼いたしました。
Demoを試そうとするとoauth_parameters_rejected=scopeとなり、とまどってしまいました。
HTBHatenaBookmarkAPIClient.m
acquireOAuthRequestTokenWithPathのscope指定が read_private,write_public となっているためですが、read_public の間違いかなと思いました。
ブックマークUIは現在presentViewController:animated:completion:
を使ってModalとして表示していますが、Contextの問題などがあるため、addSubView:
を使ってviewに貼り付ける形に変更しようと考えています。動きは現在のものと変わらない予定ですが、呼び出し方法が変わる可能性があります。
スクリーンショト: http://gyazo.com/3170f3229b76b6a7022778f47b1a54e3
アカウント: id:laiso http://b.hatena.ne.jp/laiso/bookmark
URL: http://b.hatena.ne.jp/entry/tower.jp/article/news/2013/08/15/n01/
操作手順:
HTBHatenaBookmarkViewController のツールバーのPublic <-> Private を切り替えて[Add]をタップ
発生時のソースコード:
objc
// ※Apache Cordova iOS のプラグイン向け内部APIから呼び出し
Migrate to new AFNetworking 2.0 interface. I plan to make two APiClient classes for compatibility with AFNetworking 1.x.
HTBBookmarkViewController
のナビゲーションバーにあるはてなID部分をタップするとログアウトのアクションシートが表示されますが、ユーザがこれをボタンであると判断することが難しいです。
もう少し押せるっぽさを出してほしいのですが、可能でしょうか?
簡単にid:○○○ ▼
のように後に▼をつけてあげるだけでも少し判定しやすくなると思います。
HTBHatenaBookmarkViewController などを一度 presentViewController すると、以降 HTBHatenaBookmarkViewController 以外の ViewController のモーダルアニメーションも変更されてしまうようです。
以下に再現動画を撮りました。
https://dl.dropboxusercontent.com/u/2586384/files/htbsdk.mov
ちょっと work around を入れてどうにかなるかと思ったのですが変わらずでしたので issue に登録します。
他のissueと関連する箇所がカブっているかもしれませんが、iOS 7 関連の話はまだなかったので……
2回目移行 UIActivityViewController が表示されなくなりました。
presentViewController 実行時のコンソールログ:
2013-08-22 15:22:28.794 DemoApp[40420:a0b] Warning: Attempt to present <UIActivityViewController: 0x8de56d0> on <UINavigationController: 0x8dcf650> which is already presenting <UIActivityViewController: 0x8d5bbb0>
iOS 6 SDKでビルド → iOS 7端末へインストールでも起きます。
HTBHatenaBookmarkViewController を直接 presentViewController するケースでは問題ありません。
だそうです。たしかに、iPadでモーダルビューとして表示すると、その後画面が回転したときなどに残念なことになります。
デモアプリだけの話なのですが考慮した書き方にしておいたほうがいいかなと思います。
そのままコピペするひとはいると思いますし。
On iPad, you must present the view controller in a popover.
On iPhone and iPod touch, you must present it modally.
以下、コードです。RubyMotion です。
class AppDelegate
def application(application, didFinishLaunchingWithOptions:launchOptions)
HTBHatenaBookmarkManager.sharedManager.setConsumerKey("...", consumerSecret:"...")
@window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
controller = UINavigationController.alloc.initWithRootViewController(MainViewController.new)
@window.rootViewController = controller
@window.makeKeyAndVisible
true
end
end
class MainViewController < UIViewController
def viewDidLoad
super
NSNotificationCenter.defaultCenter.addObserver(self, selector:'showOAuthLoginView:', name:KHTBLoginStartNotification, object:nil)
self.view.backgroundColor = UIColor.whiteColor
self.view << @loginButton = UIButton.rounded_rect.tap do |btn|
btn.setTitle('login', forState:UIControlStateNormal)
btn.addTarget(self, action:'on_login', forControlEvents:UIControlEventTouchUpInside)
end
self.view << @bookmarkButton = UIButton.rounded_rect.tap do |btn|
btn.setTitle('bookmark', forState:UIControlStateNormal)
btn.addTarget(self, action:'on_bookmark', forControlEvents:UIControlEventTouchUpInside)
end
if HTBHatenaBookmarkManager.sharedManager.authorized
HTBHatenaBookmarkManager.sharedManager.getMyEntryWithSuccess(
lambda { |entry| },
failure: lambda { |error| }
)
HTBHatenaBookmarkManager.sharedManager.getMyTagsWithSuccess(
lambda { |tags| },
failure: lambda { |error| }
)
end
end
def viewWillAppear(animated)
@loginButton.frame = [[0, 0], [200, 42]]
@loginButton.center = self.view.center
@bookmarkButton.frame = [[10, 10], [200, 42]]
super
end
def on_login
HTBHatenaBookmarkManager.sharedManager.logout
HTBHatenaBookmarkManager.sharedManager.authorizeWithSuccess(
lambda {},
failure: lambda {|error| NSLog(error.localizedDescription) }
)
end
def on_bookmark
controller = HTBHatenaBookmarkViewController.alloc.init
controller.URL = 'http://hbfav.bloghackers.net/'.nsurl
self.presentViewController(controller, animated:true, completion:nil)
end
def showOAuthLoginView(notification)
req = notification.object
navigationController = UINavigationController.alloc.initWithNavigationBarClass(HTBNavigationBar, toolbarClass:nil)
viewController = HTBLoginWebViewController.alloc.initWithAuthorizationRequest(req)
navigationController.viewControllers = [viewController]
self.presentViewController(navigationController, animated:true, completion:nil)
end
end
バグでは無いと思いますが、アプリケーション登録時に
read_private, write_private のscopeを有効にしていないと
[HTBHatenaBookmarkManager sharedManager] authorizeWithSuccess
のタイミングで EXE_BAD_ACCESS になるようです。
scopeが足りていないのでログイン出来ないのは正しい動きなんだと思いますが、
これが原因で先に進めていない人をTwitter上でも何人か見つけたので、念のため報告させていただきます。
※問題なければクローズしてくださいm(_ _)m
実情に合ってるっぽいので特に問題ではないのですが、直感には反するというか違和感があるので、ちょっとisssue登録してみました。
要するに最終的に表示されてるものが文字数でもバイト数でも無いので入力する文字によって増え方がまちまちなので変に感じます。
NSInteger textCount = [self.commentTextView.text lengthOfBytesUsingEncoding:NSUTF8StringEncoding] / 3;
https://github.com/hatena/Hatena-Bookmark-iOS-SDK/blob/master/SDK/UI/View/HTBBookmarkRootView.m#L201
SDKログアウト機能によってSDK内部で保持している認証アカウントはクリアされますが、
OAuth許可で利用しているHTBLoginWebViewController のはてなログイン中セッションは残ったままなので、
一度認証した後に別のアカウントで再認証するような操作ができなくなっています。
(※ 端末を再起動する or HTBLoginWebViewController内でがんばってリンクを辿ってログアウト操作すれば一応可能)
単純にCookieを削除してしまえばいいかと思ったのですが
- (void)deleteCookies
{
if(_authorizationRequest.URL){
for (NSHTTPCookie* cookie in [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:_authorizationRequest.URL]) {
[[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie:cookie];
}
}
}
こうするとアプリ内の別の場所でWebViewではてなにログインしている箇所もログアウト扱いになってしまいイマイチでした。
なので、やりたいこととしては
という感じです
HTBBookmarkViewControllerを利用して
http://matome.naver.jp/m/odai/2137604199906076101
などのモバイル向けURLをブックマーク登録をすると、登録時には正規化された
http://matome.naver.jp/odai/2137604199906076101
のブックマークエントリーとしてサーバーへ保存されますが。
再度同じURLをブックマークすると
という現象が起り、既存の入力したブックマークコメントを編集できず、常に新しく上書きにしてしまうという状態になりました。
URL正規化を解決した後にブックマークデータを取得するなどの対策が必要だと思います。
リポジトリが公開になったら、Travis CIで継続的インテグレーションできるようにする予定です。
Pocket の SDK なんかだと
PocketAPI.sharedAPI.username
で String でユーザー名が返ります。login してなければ nil
はてなブックマークのSDKでも、認証済みの場合にユーザー名が取得できるとはてなブックマークアプリみたいなのを作るときに、この SDK でユーザー管理を組み込むことができるようになるので良いと思いました。
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.