え、まじで!!
これ、TTTAttributedLabelを使っている時も、影響ありそうだなー。AppleのiOS 6とOS X 10.8AのレンダリングエンジンCoreTextのバグのため、どのアプリもアラビア語の文字列を表示しようとすると、すぐにクラッシュする。
via:AppleのCoreTextのバグでiOS 6とOS X 10.8のアプリがクラッシュ
iOS6をメインで使っている人が多いと思うので、修正版を配布した方がいいと思うのだが、どうだろうか?
常にテンパってます。
え、まじで!!
これ、TTTAttributedLabelを使っている時も、影響ありそうだなー。AppleのiOS 6とOS X 10.8AのレンダリングエンジンCoreTextのバグのため、どのアプリもアラビア語の文字列を表示しようとすると、すぐにクラッシュする。
via:AppleのCoreTextのバグでiOS 6とOS X 10.8のアプリがクラッシュ
AVCaptureSessionクラスを使ってカメラ撮影を実装する場合、sessionPresetを設定する必要があります。
こんな感じに、
AVCaptureSession *session = [AVCaptureSession new]; session.sessionPreset = AVCaptureSessionPreset1280x720;で端末によっては、対応しているかどうかわからないので、プログラム側で判断したい場合があります。
AVCaptureSession *session = [AVCaptureSession new]; if ([session canSetSessionPreset:AVCaptureSessionPreset1280x720]) { session.sessionPreset = AVCaptureSessionPreset1280x720; }else{ session.sessionPreset = AVCaptureSessionPreset640x480; }特に高解像度で写真撮影をしたいアプリを実装した時に便利かなと。
Pinterestなどでよく使われるレイヤーが表示され、さらにその上にローディング画像が現れるUIですが、実は、
SVProgressHUD
というソースが使われていることが判明。
(どうして知ったかについては、Pinterestのアプリ内のところにオープンソースの断りに書いてあったから)
前々からちょっと使ってみたいなーっと思ったので、その導入方法について書きたいと思います。
もう、めちゃくちゃ簡単で、
SVProgressHUDでソースをダウンロード。
で、次に、SVProgressHUDフォルダをそのままXcodeにコピペする。
現時点での、SVProgressHUDフォルダの構成は下記の通り。
SVProgressHUD-Prefix.pch SVProgressHUD.bundle SVProgressHUD.h SVProgressHUD.m |
#import "SVProgressHUD.h"実行は、下のたった一行で表示することができる。
[SVProgressHUD show];表示している間、そのレイヤーの下側のViewを触らせないようにマスクをつける場合は、
[SVProgressHUD showWithMaskType:SVProgressHUDMaskTypeClear];とすることで、透明なマスクをつけることができる。
[SVProgressHUD showWithMaskType: SVProgressHUDMaskTypeBlack];とすることで、マスクの色を変えることができる。
[SVProgressHUD dismiss];で非表示にすることができる。
[SVProgressHUD showSuccessWithStatus:@"saved"];と書くことにより、正常終了を表現することもできるし、失敗した場合は、
[SVProgressHUD showErrorWithStatus:@"failed"];なんてすることもできる。
そうかー、もうmacを購入して5年たつのかー。
以前、購入したmac bookを工場出荷時に戻す、つまり、初期化する方法を調べました。
具体的な方法は、下の2つのエントリーを読みながら試しました。
Mac OS X v10.6 Snow Leopard:消去してからインストールする方法
ハードディスクの初期化の方法
これ、最大の肝は、CDを入れて起動したときに「c」を押すというところがポイントかな。
それ以外は、特に問題なかった。
実は、初期化は初めて試みだったので、結構、ドキドキしましたが、終わってみると、なんてことなかったなーっと。
こんな感じでattrメソッドを使って画像をリサイズを行おうとしてもIE7とIE8でされなかった。
$('#hoge').attr({ 'width':100, 'height':100, });同じ悩みを抱えている人もいました。
$('#hoge').css({ 'width':'100px', 'height':'100px', });めでたし、めでたし。
知人から共有していただいたソースを見ると、こんな記述が。。。
<script type="text/x-jquery-tmpl"> <!-- HTML CODE --> </script>これってなんだろうーっと思って調べたら、jquery-tmplと呼ばれるプラグインのようだ。
どうやらcanvasの状態を保存して復元することができるようだ。
保存は、saveメソッド、復元はrestoreメソッドで実現することができる。
<script> jQuery(function($){ var canvas = document.getElementById("hoge"); var context = canvas.getContext("2d"); context.fillStyle = 'rgb(255, 0, 0)'; context.fillRect(0,0,100,100); context.save(); $('#restore').on('click',function(e){ context.restore(); }); $('#draw').on('click',function(e){ context.fillRect(0,0,100,100); }); context.fillStyle = 'rgb(0, 0, 0)'; }); </script> <canvas id="hoge" width="200" height="200" style="border:solid 1px red;"></canvas> <input type="button" value="restore" id="restore"> <input type="button" value="draw" id="draw">上の例では、restoreボタンを押す前に、drawボタンを押すと黒色で描画されるが、restoreボタンを押した後、drawを押すと赤色で描画される。
読了
逆算力 (成功したけりゃ人生の〆切を決めろ)
高岡 浩三 おち まさと
前回読んだ「指導しなくても部下が伸びる!」同様、日経のキャンペーンで当たった本の一冊。はじめに
via:目次
第1章 42歳で死ぬと思えば何でもできる
01 あなたは何歳で死ぬと思っていますか?
02 私が42歳で死ぬと思った理由
03 昔の42歳は「おじさん」だった
04 「生徒会選挙に出なさい」という母の教え
05 竹村健一さんのテニスコーチで学んだこと
06 「外資系企業」ネスレに入社する
07 「志」を持った就活をせよ
08 結婚も「42歳」からの逆算で決めた
第2章 最強の「サラリーマン」を目指せ
09 伝説は「マギーブイヨン」から始まった
10 取引先のパートナーが出世する幸運
11 ハタキを持ってスーパーを回る
12 全部で3回、会社をやめようと思った
13 上司によって評価が変わってはいけない
14 30歳で部長、10人超の部下を持つ
15 「要領」がよくないと社長は務まらない
16 移動時間のために事前に準備をする
17 敵ができることを恐れない
18 「骨」は崩すな
第3章 「受験にキットカット」が生まれた秘密
19 文化になった「受験にキットカット」
20 ブランドは誰のものか
21「きっと勝つ」でブランドに魂を入れる
22 異業種と組んで「ルール」を変える
23 CD付きキットカットを発売
24 『ケンミンSHOW』で解けた謎
25 アイデアが夢の中で生まれる理由
26 発想力よりも実行力
27 広告だけでは売れない時代にどう売るか
28 コスト削減も本質から考える
第4章 ネスレの強さと日本復活の条件
29 スイスの企業が強いワケ
30 100年前からグローバル企業
31 崩れた高度成長期モデル
32 日本の教育は江戸時代と同じ
33 ネスレ日本という「奇跡」
34 日本式経営の最強企業を作る
昨日のエントリーでは、canvasの透明度を調整する方法を書きました。
今日は、連続的に変更する方法について。
<script> jQuery(function($){ var nAlpha = 1; var canvas = document.getElementById("hoge"); var context = canvas.getContext("2d"); context.fillRect(0,0,100,100); function animation(){ nAlpha = nAlpha - 0.1; if(nAlpha < 0){ nAlpha = 1; } context.clearRect(0,0,100,100); context.globalAlpha = nAlpha; context.fillRect(0,0,100,100); nTimerid = setTimeout(function(){ clearTimeout(nTimerid); animation(); },200); } animation(); }); </script> <canvas id="hoge" width="200" height="200" style="border:solid 1px red;"></canvas>
canvasタグの透明度を調節する方法を調査しましたー。
こんな感じ
<script> jQuery(function($){ var canvas = document.getElementById("hoge"); var context = canvas.getContext("2d"); context.globalAlpha = 0.5; context.fillRect(0,0,100,100); }); </script> <canvas id="hoge" width="200" height="200" style="border:solid 1px red;"></canvas>
昨日は、アプリ内でメール機能を実装する方法について書きましたが、SMSも同様にURLschemeを呼ばなくても自分のアプリ内で呼び出すことができます。
//phoneはメッセージを送りたい電話番号 NSString *phone; //messageは、SMSのメッセージ内容 NSString *message; UIViewController *viewController; if ([MFMessageComposeViewController canSendText]) { mFMessageComposeViewController.messageComposeDelegate = self; mFMessageComposeViewController.recipients = @[phone]; mFMessageComposeViewController.body = message; [viewController presentModalViewController:mFMessageComposeViewController animated:YES]; } //MFMessageComposeViewControllerDelegate - (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result{ }設定項目がわずかなので、メール機能よりも便利ですねー。
前回、アプリ内でアドレス帳内にあるメールアドレスを取得する方法を書きましたが、今回は、メールアプリを起動せずに、自分のアプリ内でメール機能を実装する方法について書きたいと思います。
以下のようなソースで呼び出すことができる。
//emailは、送信先のメアド NSString *email = @""; //mailtitleは、メールアドレスのタイトル NSString *mailtitle = @""; //messageは、メールの内容 NSString *message = @""; UIVIewController *viewController; if ([MFMailComposeViewController canSendMail]) { mailComposeViewController.mailComposeDelegate = self; [mailComposeViewController setToRecipients:@[email]]; [mailComposeViewController setSubject:mailtitle]; [mailComposeViewController setMessageBody:message isHTML:NO]; [viewController presentModalViewController:mFMessageComposeViewController animated:YES]; } //MFMailComposeViewControllerDelegate -(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error: }この実装で呼び出すことができる。
昨日は、アドレス帳の電話番号を取得する方法を書きましたが、今日は、メールアドレスの取り方について。
下のようなソースコードでできる。
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person{ return YES; } - (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier{ NSString *email; //メールアドレスの場合 if (property == kABPersonEmailProperty) { //複数件数あるかどうかの確認 ABMultiValueRef emails = ABRecordCopyValue(person,kABPersonEmailProperty); email = (__bridge NSString*)ABMultiValueCopyValueAtIndex(emails,identifier); return NO; } return NO; } - (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker{ [self dismissViewControllerAnimated:YES completion:NULL]; }これも実機で正常終了しましたー。
前回、アプリ内でiOSの中にあるアドレス帳を開く方法を書きました。
今回は、選択された項目が電話番号の場合の取得方法について。
次のようなソースコードで得られる。
//ABPeoplePickerNavigationControllerDelegate - (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person{ return YES; } - (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier{ NSString *phone; //電話番号の場合 if(property == kABPersonPhoneProperty){ //複数件数あるかどうかの確認 ABMultiValueRef phones = ABRecordCopyValue(person,kABPersonPhoneProperty); phone = (__bridge NSString*)ABMultiValueCopyValueAtIndex(phones,identifier); return NO; } return NO; } - (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker{ [self dismissViewControllerAnimated:YES completion:NULL]; }実機で試した結果、正常終了しました。
どうやらアプリ内で、アドレス帳を開くことができるようだ。
その方法を書きたいと思います。
まずは、下の二つのライブラリーが必要です。
AddressBook.framework AddressBookUI.framework表示したいViewController.hに下のコードを記述。
#import <AddressBookUI/AddressBookUI.h>表示したいViewController.mに下のコードを記述。
ABPeoplePickerNavigationController *aBPeoplepicker; aBPeoplepicker = [[ABPeoplePickerNavigationController alloc] init]; aBPeoplepicker.peoplePickerDelegate = self; [self presentModalViewController:aBPeoplepicker animated:YES];ただし、これだけだとクラッシュしてしまう、理由は、delegateを設定していないから。
//ABPeoplePickerNavigationControllerDelegate - (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person{ return YES; } - (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier{ return NO; } - (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker{ [self dismissModalViewControllerAnimated:YES]; }こうすればクラッシュすることなく、下のようにアドレス帳にアクセスしてもいいかどうか問うアラートが表示されます。
前回、app centerに登録するときの注意点について書きました。
で、実際にFacebook App Centerに提出して通ったので、その時の注意点をまとめたいと思います。
Privacy Policyは必須。かつ、外部サイトに作ること。
最初、Facebook Pagesのノートに書いていたのですが、いつまで立っても審査されず、外部のレンタルサーバーを借りてそこに移したところ、審査が始まりました。
Terms of Seriveは必須。かつ、外部サイトに作ること。
Privacy Policyと同様に、最初、Facebook Pagesのノートに書いていたのですが、いつまで立っても審査されず、外部のレンタルサーバーを借りてそこに移したところ、審査が始まりました。
ちなみに、上の二つのサイトは、日本語でも問題ないようです。
スクリーンショットは、iOSの画面をそのまま掲載すること。
AppleのApp Centerのように、余計なエフェクト入れたりはせず、ありのままの、画像を掲載すること。
以上の注意点を守って、次回以降のアプリも審査に出したいです。
ちなみに、プライバシーポリシーや利用規約のひな形は、以前、紹介した良いウェブサービスを支える「利用規約」の作り方を読んで作りました。
読了
指導しなくても部下が伸びる!
生田洋介
どうやら日経の会員登録キャンペーンか何かであたって、いつの間にか家に突然、届いていた。序章 “指導者”ではなく“促進者”になれ
via:目次
新しいチームがスタートするとき
プロジェクトが動きだすとき
仕事を任せるとき
日常業務のなかで
面談の場で
会議の場で
ランチ・飲み会などの場で
部下が失敗したとき
部下が成功したとき
プロジェクトが終了したとき
終章 あなた自身が手本たれ
iOS上であるアカウント情報を取得するにはどうすればいいのだろうか?
GET users/showを読みながら下のように実装しました。
#import <Twitter/Twitter.h> TWRequest *tWRequest = [[TWRequest alloc] initWithURL:[NSURL URLWithString:@"https://api.twitter.com/1.1/users/show.json"] parameters:[NSDictionary dictionaryWithObject:@"問い合わせをしたいTwitterのID" forKey:@"user_id"] requestMethod:TWRequestMethodGET]; //下のacAccountは、ACAccount型の変数 tWRequest.account = acAccount; dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0); dispatch_async(queue, ^{ [tWRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error){ if(!error){ NSDictionary *dictJSON = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:nil]; dispatch_async(dispatch_get_main_queue(),^{ }); } }]; });上を実行した結果、正常終了しましたー。
当初想定では、下のコードの出力結果は、barになると思ってしたのだが、実際は、「hoge」だった。
NSString *hoge = @"hoge"; NSString *foo = hoge; hoge = @"bar"; NSLog(@"%@",foo);NSStringの値設定は、参照渡しになると解釈していたのだが、これだけみると値代入になっている気がする。なぜ??
TWRequestクラスを使ってリクエストを飛ばそうと実装しているのですが、認証が必要な場合、下のように実装しました。
ACAccount *acAccount; TWRequest *tWRequest = [[TWRequest alloc] initWithURL:[NSURL URLWithString:@"https://api.twitter.com/1.1/users/show.json"] parameters:[NSDictionary dictionaryWithObject:@"" forKey:@"user_id"] requestMethod:TWRequestMethodGET]; tWRequest.account = acAccount; [tWRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error){ }];で、ここでクラッシュしてしまう。
前回、Twitterのアカウントの使用許諾を得るために、Twitterの認証を行うというエントリーを書きました。
ACAccountStoreのrequestAccessToAccountsWithTypeメソッドを使って、usernameやらidを取得することができるのですが、そのメソッド内部で、Viewの更新を行うととてつもなく時間がかかることが判明。
具体的には、こんな感じ。
ACAccountStore *aCAccountStore = [[ACAccountStore alloc] init]; ACAccountType *aCAccountType = [aCAccountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter]; [aCAccountStore requestAccessToAccountsWithType:aCAccountType withCompletionHandler:^(BOOL granted, NSError *error) { if (granted) { //問題個所(ものすごく時間がかかる) UIVIew *hoge; [self.view addSubView:hoge]; }else{ NSLog(@"not grandted"); } }];どうしてかなーっと思って調べたら、ACAccountStoreのcompletionHandlerはサブスレッドっぽいでサブスレッドであることが反映。従って、gdcを使って、メインスレッドで処理を書けばいいことがわかる。下のような感じ。
ACAccountStore *aCAccountStore = [[ACAccountStore alloc] init]; ACAccountType *aCAccountType = [aCAccountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter]; [aCAccountStore requestAccessToAccountsWithType:aCAccountType withCompletionHandler:^(BOOL granted, NSError *error) { if (granted) { main_queue = dispatch_get_main_queue(); dispatch_async(main_queue, ^{ UIVIew *hoge; [self.view addSubView:hoge]; }); }else{ NSLog(@"not grandted"); } }];実行した結果、無茶苦茶早くなりました。
facebookのAPIように大小異なるプロフィールイメージをTwitterでは取得できないのかなーっと調べていたら、取得できるようです。
Variant | Dimensions | Example URL |
---|---|---|
normal | 48px by 48px | http://a0.twimg.com/profile_images/xx/xx_normal.png https://si0.twimg.com/profile_images/xx/xx_normal.png |
bigger | 73px by 73px | http://a0.twimg.com/profile_images/xx/xx_bigger.png https://si0.wimg.com/profile_images/xx/xx_bigger.png |
mini | 24px by 24px | http://a0.twimg.com/profile_images/xx/xx_mini.png https://si0.twimg.com/profile_images/xx/xx_mini.png |
original | original | http://a0.twimg.com/profile_images/xx/xx.png https://si0.twimg.com/profile_images/xx/xx.png Omit the underscore and variant to retrieve the original image. The images can be very large. |
昨日のエントリーでUITableViewCellの横幅がわかったことを書いたのですが、では、それを踏まえて動的に変更することはできないのだろうか?
UITableViewDelegateプロトコルの- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPathを使って下のように実装しても変更することができなかった。
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath cell.frame = CGRectMake( cell.frame.origin.x, cell.frame.origin.y, 200, cell.frame.size.height ); }何故なんだろう?
UITableViewControllerのUITableViewStyleがUITableViewStyleGroupedのときのUITableViewCellのwidthって一体いくつなのか気になって調べました。
Width of grouped UITableViewCell
によると300とのことです。
こうしてメモしておくと、アプリを作る上での一つの目安になって便利ですね。
Instagramの認証を読みながら実際に、ログイン方法について調べる。
Google App Engineを使った場合は、下のように実装できるようだ。
#!/usr/bin/env python # -*- coding: utf-8 -*- # # Copyright 2007 Google Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # import webapp2 import json import urllib from google.appengine.api import urlfetch class LoginInstagram(webapp2.RequestHandler): def get(self): self.redirect("https://api.instagram.com/oauth/authorize/?client_id=hoge&redirect_uri=http%3A%2F%2Ffoo.appspot.com%2Ftest%2Finsta%2Fredirect&response_type=code") class RedirectFromInstagram(webapp2.RequestHandler): def get(self): self.response.headers['Content-Type'] = 'text/plain' code = self.request.get('code') url = "https://api.instagram.com/oauth/access_token" payload = urllib.urlencode({ "client_id":"hoge", "client_secret":"hoge_secret", "grant_type":"authorization_code", "redirect_uri":"http://foo.appspot.com/test/insta/redirect", "code":str(code) }) result = urlfetch.fetch( url=url, payload=payload, method=urlfetch.POST, headers={'Content-Type': 'application/x-www-form-urlencoded'} ) if result.status_code == 200: #tokenの表示 self.response.out.write(result.content) app = webapp2.WSGIApplication([ ('/test/insta', LoginInstagram), ('/test/insta/redirect', RedirectFromInstagram) ],debug=False )Oauth2だとこんなに簡単なものかとびっくりしてしまった。
ある特定のアプリを立ち上げているとよく「このアプリを評価してくれませんかー」というアラートが表示されるのですが、どうやって実装されているんだろうーっと思っていたら、どうやらAppiraterというオープンソースのコードが使われている模様。
実際に、
アプリのレビューを促すメッセージを表示するAppiraterライブラリの導入手順
を見ながら今、リリースしているアプリに導入しましたー。
上のエントリーを読みながら実装するとめちゃくちゃ早くできるので、便利ですよ。
読了
大失敗!―成功企業が陥った戦略ミステイクの教訓
ジャック トラウト
大企業が犯した数々の失敗を網羅している一冊。
最後の方にコンサルをdisっているのだが、読んでいて大丈夫なのだろうか?と心配せずにはいられなかった。訴えられないだろうか?読んでいる人の中には、コンサル会社を特定できそうな気がするのだが。
失敗にはある一定の法則があることが本書を読んで把握することができる。
同じ失敗を繰り返さないためにも、読んでおいて損はない一冊。
仕事をしていて思うのは、自動でHTMLを作ってくれるサービスがあれば、そこそこいけるんじゃないかと。
で、日常生活をしていていくつか発見したので、共有
wix
weebly
amsstudio
strikingly
引用元:シンプルで美しいウェブサイトをたった数分で作成できるサービス「Strikingly」
2013年10月01日:追記
appcubator
引用元:Web“ページ”ではなく“サイト”を一般会社員にも作れるAppcubator(データベースやアクセス分析も最初から提供)