カテゴリー ‘ MacOS/iOS Dev.

Mac OSでも楽チン Facebook編 その2 Social.framework

まずは下準備。FBにアプリケーション登録をする。登録画面には、iOSはあるもののOS X用のアプリケーションを登録する場所がない。とりあえず「ネイティブiOSアプリ」を選択しておいて問題ないようだ。次にBundle IDを作成するアプリケーションと同じにしておく。次に詳細設定でApp Typeを「Native/Desktop」にApp Secret in Clientを「いいえ」にする。これで終了。

今まで一度もFBのアプリは作ったことがないのでイマイチ手順が分からないが、とりあえず何かをリクエストしてみる。

	ACAccountStore *accountStore = [[ACAccountStore alloc]init];
	ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
	NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:@"取得したAppID",ACFacebookAppIdKey,
					[NSArray arrayWithObjects:@"publish_stream",@"publish_actions",nil],ACFacebookPermissionsKey,nil];
	[accountStore requestAccessToAccountsWithType:accountType options:options completion:^(BOOL granted, NSError *error) {
		if(granted){
			NSArray *accounts = [accountStore accountsWithAccountType:accountType];
			ACAccount *anAccount = [accounts lastObject];
			NSLog(anAccount: %@,[anAccount description]);
		}else{
			NSLog(@"error: %@",[error description]);
		}
	}];

結果は、
The Facebook server could not fulfill this access request: The app must ask for a basic read permission at install time.”

インストールした直後はまず、基本情報のパーミッションをリクエストしないといけないようだ。(install timeってそういうことでいいのかな?)

続きを読む

Mac OSでも楽チン Facebook編 その1 NSSharingService

前回タイトルを楽チン ツイートにしてしまったので、フェイスブックにかえるとなんだけヘンテコなタイトルになってしまった。

OS X 10.8.2 になって Facebook連携にも対応した。10.8で既にTwitter連携は搭載済だったが、Facebookも同様に楽チンに連携できるのか試してみた。
もちろん、FBアカウントは取得済みで、アカウントを「システム環境設定:メール/連絡先/カレンダー」に登録しておく必要がある。(ちなみにFBのテストアカウントは登録できなかった。)
まずはTwitter同様にNSSharingServiceから。同様にNSSharingServiceDelegateプロトコルを追加して、

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification{
	NSSharingService *service = [NSSharingService sharingServiceNamed:NSSharingServiceNamePostOnFacebook];
	service.delegate = self;
	[service performWithItems:[NSArray arrayWithObject:@"hello"]];
}

すると、

ダイアログが表示された。左上で公開範囲を指定できる。
一つ分からないのだが、FBでは本文中のURLにプレビューがつくようなのだが、これを実現する方法がわからない。Safariの共有から投稿するとそのページのプレビューが一緒に投稿できるが、performWithItemsにNSURLを突っ込んでもNSStringで文中にhttp://から始まる文書をいれても同じようにならない。さてどうするのかな?

UISearchBarDelegate textDidChangeが通知しない?

iOSのアプリケーションをiOS6, iPhone5に対応させるべくアップデートをおこなったが、バグ?という現象にであった。
UISearchBarDelegateのsearchBar:textDidChange:が通知されない。といってもソース上から値を代入した時(self.searchBar.text = @”hoge”など)の話であって、キーボードからのテキスト編集では通知される。もちろんiOS5などでは通知されている。ちなみにUITextFieldTextDidChangeNotificationも同様に通知されない。searchBarTextDidEndEditing:は通知されている。とりあえず、別方法で処理するしかなさそうだ。

Xcode4.5, iOS6 SDK

App sandbox not enabled またまたドはまり

Xcode4.5に上げて、MacAppStore用のアプリケーションをアップデートするべくオーガナイザからサブミットした。
前回の「ヘルパーアプリ使用時のValidationエラー Invalid Code Signing Entitlements.」問題が解決されていることを期待したが、残念ながら全く変わっていなかった。
なので前回同様の処理をしてバリデーションを通して、サブミットした。しかしすぐにiTunesConnectからメールレス、「App sandbox not enabled」としてバイナリーリジェクトをくらってしまう。設定を変えてしまったかと思い幾つか試してみるが、何度やっても同じ。なので、前回のアーカイブと内容をくらべてみた。しかしほとんど違いがみつからない。

もちろんxxx.entitlementsも

<key>com.apple.security.app-sandbox</key>
<true/>

となっている。
しかたがないので、一旦Xcode上でヘルパーをデベロッパ用でコードサインを使って、SignatureのCodesign applicationをオンして、アーカイブ。ところがアーカイブを見ると前回のサブミットには入っていない「archived-expanded-entitlements.xcent」がリソースに入っている。内容はxxx.entitlementsと同じ。

アーカイブを開いてヘルパーの

  • _CodeSignature
  • embedded.provisionprofile

を削除した後にターミナルでコードサインし、無事レビュー待ちになった。泣けてきた。

Mac OS X 10.7.5, Xcode4.5, OS X 10.8 SDK

[その後]
10/23 無事通過しました。20日待ち。長っ!

Twitter API ルール変更 RSS配信の終了

API1.1のその後情報なのだが、さらにRSSの配信を打ち切ることに決めたそうだ。具体的にはAPIからのデータ取得形式をJSONのみにするということなのだが、これでは既存のRSSリーダーでは読めなくなってしまう。更新をわざわざ手動確認するのも面倒なので、本家アプリのみだとツイートの存在を忘れちゃうかもしれないな。

しかし、Safariも6 からバッサリとRSSリーダを切り落としてまった。むしろこちらの動きの方が気になるくらい。あれだけWeb2.0だとかサービスだとかともてはやされたのに徐々にフェードアウトしていくのだろうか?

とりあえず、CocoaからのJSONパースは json-framework がよさそうだ。とても楽にパースできる。

下記で大変親切に説明してくれている。

JSONをパースしてくれるCocoaライブラリ – おいしいCocoaの飲み方

Twitter API ルール変更 どうなる?

楽チン ツイートと喜んでいるのもつかの間、ここのところTwitter APIのルールが変更されたということで話題になっている。まだよく理解できていないのが正直なとこだが、個人的に気になったのは、

  1. 全てのAPIで認証が必要
  2. 1時間当りのAPIアクセス数が60回に制限
  3. ディスプレイガイドラインに準拠が必要
  4. 基本は10万ユーザー以上に使用してもらえない

というところかな。

私のMacアプリケーション「MeNews」では、タイムラインの取得とSearch APIによるツイートの取得のふたつをやっている。従来、Search APIは認証の必要がなかったので、気軽に結果だけを取得していた。たぶんこれが、1.に引っかかることになるんだろう。ただタイムライン取得ですでにOAuth認証ができているので改変はそう問題ではないと思う。しかし2.の60回の制限にかかるとなると、この部分すこし考えなくてはならない。

3.のディスプレイガイドラインというのが具体的にどんなものかよくわからないのだが、取得したツイートの表示方法を限定されるような内容であると根本的な見直しが必要になりそう。

4.は、残念ながらとても相手にしてもらえるような数字ではないのだが、ほとんどの人が公式のアプリを使っているのだろうから、共栄していけばいいのではと思うのだが。もともととても開かれたAPIだったのだから。

しかし、iOSやMacの楽チン系のframeworkの場合このルールとはどのように影響するのだろう? きっと、作成したアプリはすべてiOS か OSX のTwitter Integrationからのアクセスということになると思うのだけど...

もうすこし調べてみたい。

Mac OSでも楽チン ツイート その2 Social.framework

アプリケーションからとにかく簡単にツイートしたい時は、前出のNSSharingServiceを使うのが最も簡単な方法の用だが、タイムラインを取得したり、よりカスタマイズをしたいという場合は、10.8より追加された、Social.frameworkのSLRequestを使用するのが良さそうだ。このクラスは使い勝手としては、iOS5から搭載されたTwitter.frameworkのTWRequestにそっくりで、こちらも非常に楽チンだ。

では、まずはFrameworksに”Social.framework”とAccounts.frameworkを追加する。次にヘッダをそれぞれインポート<Social/Social.h><Accounts/Accounts.h>。以上で準備完了。

つぎにツイートをするにはこんな感じ。

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification{
    ACAccountStore *accountStore = [[ACAccountStore alloc]init];
    ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
    [accountStore requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error) {
        if(granted){
            NSArray *accounts = [accountStore accountsWithAccountType:accountType];

            if (accounts != nil && [accounts count] != 0) {
                ACAccount *twAccount = [accounts objectAtIndex:0];
                NSURL *url = [NSURL URLWithString:@"https://api.twitter.com/1/statuses/update.json"];
                NSDictionary *params = [NSDictionary dictionaryWithObject:@"Hello" forKey:@"status"];
                SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:url parameters:params];
                request.account = twAccount;
                [request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
                    NSString *output = [NSString stringWithFormat:@"HTTP response status: %ld",[urlResponse statusCode]];
                    NSLog(@"%@", output);
                }];
            }
        }
    }];
}

このようにiOSのTWRequestとほぼ同じ。既にシステムに登録済のアカウントを取得して、それを使ってツイートする。このようにTwitter本家で認証した後にツイートする従来の手法に比べ認証を手前で用意する必要がない分、飛躍的に楽チンができる。

次にタイムラインを取得してみる。

続きを読む

Mac OSでも楽チン ツイート その1 NSSharingService

iOS5では既に実現されている楽チン ツイートが10.8よりMac OSでも可能になった。

ざっくり分けると

  • NSSharingService
  • Social.framework

かと思われる。前者はSafari6の共有ボタンに見られるツイート機能と同じく、最も簡単にアプリケーションからツイートすることができる。ツイートのみでなくタイムライン取得やカスタマイズがしたい場合は後者を使うことになりそうだ。

まずは、NSSharingService。

NSSharingServiceDelegateプロトコルを追加して、

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification{
	NSSharingService *service = [NSSharingService sharingServiceNamed:NSSharingServiceNamePostOnTwitter];
	service.delegate = self;
	[service performWithItems:[NSArray arrayWithObject:@"hello"]];
}

これだけ。実行すると次が表示される。

びっくりするほどシンプル。
ただし、事前に [システム環境設定 > インターネットとワイヤレス > メール/連絡先/カレンダー]でツイッターアカウントを登録しておく必要がある。もし、していなくてもアカウントの追加に導いてくれるのでこれまた楽チン。

もちろんツイッター以外の共有サービスも使用可能。Facebookは秋頃に追加されるらしい。

さらに、NSSharingServicePickerを使用するとまるっきり共有ボタンができてしまう。
これも、NSSharingServicePickerDelegateプロトコルを追加して、
適当なNSButtonを配置し下記アクションを接続する。

- (IBAction)twAction:(id)sender {
	NSSharingServicePicker *picker = [[NSSharingServicePicker alloc]initWithItems:[NSArray arrayWithObject:@"Hello"]];
	picker.delegate = self;
	[picker showRelativeToRect:[sender bounds] ofView:sender preferredEdge:NSMinXEdge];
}

またまた、これだけ。次のように共有ボタンが作成できた。


以上の2つだけで、イメージなどを含むツイートなども作成できるようだ。

iOS3と3G すでに懐かしい

iPhone 3Gを使っていた頃、iOS4にするとそれはもうストレスの塊になるほどモッサリ動作になってしまった。なので、マルチタスクもフォルダも羨ましく横目に見ながら意地で3.1.3のまま使い続けていた。そんなこともあって、作成したiPhoneアプリは3.1.3から動作をするように作っている。今回、私の初リリースアプリ、「誰ナン?」(なぜかiPhoneでできない連絡先の電話番号検索アプリ)に若干機能を加えてAppStoreにアップしようとしたのだが、実機テスト(iOS3.1.3 & iPhone 3G)を使用とすると動かない! コンソールを見ると、下記のようなエラーが起こっていた。

dyld: Symbol not found: __NSConcreteGlobalBlock

他のOSでは問題ないのでどうやらiOS3上だけのエラーのようだ。早速、調べてみるとこれもまたズバリを書いておられる方がいました。

libSystem.B.dylibってなんだろう

早速、対処をして無事動くようになった。記事を書いておられる方、ありがとうございます。

しかし、既にiOSは5.1となり既に6も見えているような状況。いつまで対象に含めるかと考えるが、既にリリース済みのアプリについてはできるだけ対応したいと思っている。

Xcode4.4, iOS SDK 5.1

ところで、iPhone 3Gの日本国内発売はたしか北京オリンピックの年だったかな? 4年でえらい進歩しますなぁ。

ヘルパーアプリ使用時のValidationエラー Invalid Code Signing Entitlements.

先日のアプリケーションの自動起動の件は一件落着したように見えたのだが、これをMac App Storeにサブミットするときに、はまりまくってしまった。

サブミット時は素直に行った事がないのだが、いくつかのエラーを一つずつ潰していた結果下記のエラーがどうしてもクリアできなくなった。

全然エラーの見当がつかず、再度証明書を作ってみたり悪あがきをしてみたが、まったく改善せず。もう一度、はじめに戻ってヘルパーアプリをターゲットから外してみるとあっさり通過した。

プロビジョニングファイルは次の通り。これをそれぞれのターゲットのCodesign Identityにセットした。

  1. Main.app開発用
  2. Main.app運用用
  3. Helper.app開発用
  4. Helpeer.app運用用

また、Main/Helperともにサンドボックスを有効にしている。

以上で再度アーカイブするが、やはり同エラーで先に進めない。う〜ん。困った。どうしよう。
そうこうしているうちにまた、下記のような情報に出会った。

Submit an OSX App with helper App in its bundle

理由はよくわからないのだが、一旦作成した、アーカイブの中のHelper.appを再度コードサインしなさい、ということだ。(と思う)もう一歩も前に進めないので、書かれている通りにヘルパーアプリを再度コードサインして、embedded.provisionprofileを削除してみた。結果はあっさりValidationを通過したのだが、喜んだのもつかの間、直ぐにiTunesConnectからInvalid Binaryとして突き返されてしまった。

こうなったら最後まで悪あがきをしようと、決めて、今度はHelper.app側のみをDon’t Codesignとして、アーカイブ。そして、ターミナルでコードサインしてみた。これでValidationも通り現在、Waiting for reviewになっている。
しかし、本当にこれで正解なのかはいまだにわからない。何日かすれば判定だけはくだされるんですけどね。

あと、調べている最中にもう一つの解決策として、ワイルドカードを使用したというのも見かけた。これで解決できるのかは試していないので不明。

 

[2012.8.11 追記]
上記設定で無事審査を通過しました。しかし、毎度この設定は面倒なので、はやく改善していただきたいものだ。
それにしても、審査待ち時間長過ぎる。 10.8リリースと重なったので仕方ないのでしょうね。

return top