新しいiOSアプリをリリースしたのでお知らせします。
cameramaticはシンプルなiPhone/iPod touch向けのトイカメラアプリです。
難しい設定は一切不要で、付属しているフィルタとフレーム組み合わせると普通とはちょっと雰囲気の違う写真を簡単に撮影することが可能になっています。
Cameramatic
http://www.mudaimemo.com/iphone/cameramatic/
新しいiOSアプリをリリースしたのでお知らせします。
iOS4になってから画像のEXIFを読み込んだり書き込んだりすることができるようになりました。
UIImagePickerを利用していればdelegateで呼ばれるメソッドの引数にメタデータが格納されています。
カメラロールに保存する場合は ALAssetsLibrary:writeImageToSavedPhotosAlbum:metadata:completionBlock:
を使えばメタデータも一緒に格納できます。(iOS4.1以上)
ただ、画像のメタデータを直接書き換える方法がよく分からなくてハマってしまいました。
検索してもめぼしい情報があまり見当たらず四苦八苦して実現したので一応メモしておきます。
#import <ImageIO/ImageIO.h>
#import <MobileCoreServices/UTCoreTypes.h>
- (NSData *)addMetadata:(UIImage *)image {
NSMutableData *imageData = [[[NSMutableData alloc] init] autorelease];
// メタデータ
NSMutableDictionary *metadata = [NSMutableDictionary dictionary];
// メタデータ: 画像の高さと幅
[metadata setObject:[NSNumber numberWithInt:1000]
forKey:(NSString *)kCGImagePropertyPixelHeight];
[metadata setObject:[NSNumber numberWithInt:1000]
forKey:(NSString *)kCGImagePropertyPixelWidth];
// メタデータ: Exif
NSMutableDictionary *exif = [NSMutableDictionary dictionary];
exif = [metadata objectForKey:(NSString *)kCGImagePropertyExifDictionary];
[exif setObject:@"ユーザーコメント" forKey:(NSString *)kCGImagePropertyExifUserComment];
[metadata setObject:exif forKey:(NSString *)kCGImagePropertyExifDictionary];
// CGImageDestination を利用して画像とメタデータをひ関連付ける
CGImageDestinationRef dest;
dest = CGImageDestinationCreateWithData((CFMutableDataRef)imageData, kUTTypeJPEG, 1, nil);
CGImageDestinationAddImage(dest, image.CGImage, (CFDictionaryRef)metadata);
CGImageDestinationFinalize(dest);
CFRelease(dest);
return imageData;
}
ふとしたきっかけでdeallocが呼ばれないUIViewControllerのサブクラスができてハマってしまいました。
小ネタですがメモしておきます。
[self.navigationController popViewControllerAnimated:YES];
@interface MyTableView : UITableView
{
MyViewController *myViewController;
}
@property (nonatomic, retain) MyViewController *myViewController;
@end
@interface MyViewController : UIViewController
{
MyTableView *myTableView;
}
@property (nonatomic, retain) MyTableView *myTableView;
@end
@implement MyViewController
@synthesize myTableView;
- (void)loadView {
[super loadView];
self.myTableView = [[MyTableView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
myTableView.myViewController = self;
[self.view addSubview:myTableView];
}
- (void)dealloc { // なぜかこれが呼ばれない
[myTableView release];
[super dealloc];
}
@end
どうもmyTableView.myViewController = self;
このようにpropertyのpropertyにselfを指定してしまうとdeallocが呼ばれなくなるようです。- (void)viewDidDisappear:(BOOL)animated {
[super viewDidAppear:animated];
if (self.parentViewController == nil) { // popされた時のみ実行される
myTableView.myViewController = nil;
}
}
// NSArrayのプロパティにselfを格納する
self.dataSourceArray = [NSArray arrayWithObjects:self, obj1, obj2, nil];
NSArrayに(NSDictionaryも)値を入れるとその時点でretainCountがひとつ増えます。dataSourceArray = nil;
としてやる必要があります。
Facebookのユーザーが日本でも増えてるらしいのでFacebookのAPIを使って何かできたらなと思い、とりあえず認証の仕組みを調べてみたのでざっくりとしたメモを残しておきます。
基本的にWebアプリの話です。
iOSアプリの場合はiOS用のSDKをごにょごにょすればあんまり難しいことを考えずにすみます。
なにはともあれ、ドキュメントはこちら
Authentication - Facebook Developers
http://developers.facebook.com/docs/authentication/
Facebookの認証はWebアプリでもデスクトップアプリでもOAuth2.0を利用しています。
Twitterの認証もOAuthなのですが、TwitterのほうはOAuth1.0なので仕様が異なります。
また、Twitterの認証は 「認証即全権限付与」という感じなのですが
Facebookでは パーミッションの付与 -> 認証 という流れになっています。
デフォルトではユーザーのプロフィール情報などのみ取得できます。
メールを送信したり写真/ビデオを扱うためには別途パーミッションをリクエストする必要があります。
以上を踏まえた上で、実際に認証するコードが下のようになります。
facebookが用意しているPython用のコードから一部抜き出しています。
# アプリの設定ページでApplication ID, Application Secretを確認しておく
# http://www.facebook.com/developers/apps.php
FACEBOOK_APP_ID = 'app_id'
FACEBOOK_APP_SECRET = 'app_secret'
class LoginHandler(BaseHandler):
def get(self):
verification_code = self.request.get("code")
args = dict(client_id=FACEBOOK_APP_ID, redirect_uri=self.request.path_url)
if self.request.get("code"):
# authorizedされたらcodeが飛んでくる
# そのcodeを利用してaccess_tokenを取得するリクエストを投げる
args["client_secret"] = FACEBOOK_APP_SECRET
args["code"] = self.request.get("code")
content = urllib.urlopen(
"https://graph.facebook.com/oauth/access_token?" +
urllib.urlencode(args)).read()
# access_token=***&expires=*** というクエリストリング形式の文字列が返ってくるのでパースする
response = cgi.parse_qs(content)
access_token = response["access_token"][-1]
# access_tokenがゲットできたらプロフィール情報も取得できる
profile = json.load(urllib.urlopen(
"https://graph.facebook.com/me?" +
urllib.urlencode(dict(access_token=access_token))))
self.redirect("/")
else:
# 認証用のコードがなければauthorizeへリダイレクト (パーミッションの確認)
self.redirect(
"https://graph.facebook.com/oauth/authorize?" +
urllib.urlencode(args))
その他、Cookieを仕込んだりaccess_tokenやプロフィール情報をストレージに格納したりログアウト処理の実装は割愛今更感ありありですが最近お世話になったのでご紹介。
アプリやWebサイトを紹介する時にとても重宝します。
iPhone ScreenTaker ※ Mac限定
http://fabian-kreiser.com/
ダウンロードは上のリンクの「DOWNLOADS」 → 「IPHONE SCREENT.」
アップデートのお知らせです。
アップデートのお知らせです。
iPhoneアプリ Monochromia のversion1.3.0をリリースしました。
変更点:
セピアやヴィンテージ調などの各種フィルタを追加
粒状感のコントーロール機能を追加
ファジー・モードを削除
Vintage Blue
Vintage Red
Red Highlight
新しくiPhoneアプリをリリースしたのでご紹介。
新しくiPhoneアプリをリリースしたのでご紹介します。
BinaryCamera LiteがApp storeでダウンロード可能になってから1週間経過しました。(App Store)
これからiPhone/iPadアプリをリリースしようとしている人、リリースしている人、とにかく興味がある人向けに、リリース後1週間でどれくらいダウンロードされたかさらしてみます。
参考程度に有料版のBinaryCameraのデータもならべてみました。
(こちらはリリースから1ヶ月ほど経過しています)
それでは、こちらが1週間のダウンロード数の変移です。