アイテム' + itemCount + '
' + '詳細' + itemCount + '
' + 'iOS6からTwitter.frameworkが非推奨になりました。 将来的なことを考えて「Social.framework」に移行する必要があります。
といってもframeworkの読み込めば、名称変更するだけで従来の機能が利用できます。
SLComposeViewController *composeViewController = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
[composeViewController setInitialText:[self createTweetComment]];
[self presentViewController:composeViewController animated:YES completion:NULL];
composeViewController.completionHandler =
^(SLComposeViewControllerResult result) {
switch (result) {
case SLComposeViewControllerResultDone:
NSLog(@"SLComposeViewControllerResultDone");
//[self completeTweet];
break;
case SLComposeViewControllerResultCancelled:
NSLog(@"SLComposeViewControllerResultCancelled");
break;
default:
NSLog(@"error");
break;
}
[self hideLoadingDialog];
[self dismissViewControllerAnimated:YES completion:NULL];
};
iOS6から、Viewを遷移する「presentModalViewController」や「dismissModalViewControllerAnimated」等が非推奨になっています。
[ccp] [self presentViewController:leaderboardController animated:YES completion:NULL]; [self dismissViewControllerAnimated:YES completion:NULL]; [ccp]
「completion:」で画面遷移後の処理をblock文で記述します。 前からこの機能が欲しかったですよね。
Xcodeが全く操作できないくらい遅くなりました。
調べたら、コード補完用の検索インデックス(Indexing)で負荷がかかっているみたいです。
defaults write com.apple.dt.Xcode IDEIndexDisable 1
Xcode再起動後に、動作が軽くなりました!
が、しかしコード補完自体はできるのですが、ヒエラルキー「Symbol Not Found」とかで使えません。 これでは不便なので、元に戻します。
defaults write com.apple.dt.XCode IDEIndexDisable 0
Xcode再起動後Indexingが再度行われて、現状軽いままXcodeは動作しています。
indexに無駄な情報が蓄積されるのが原因なんでしょうか?
プロジェクト単体で重い場合は、Organizerで不要ファイルを削除します。
HTML5エキスパートで有名な吉川さん(同性w)からCodeIQの問題があったので挑戦!
「DOM操作の最適化によるJavaScriptチューニングにチャレンジ!」
var button = document.querySelector('button'),
ul = document.querySelector('#output'),
itemCount = 0;
function addItems() {
for ( var i = 0; i < 10; i++ ) {
itemCount++;
ul.innerHTML += ''
+ 'アイテム' + itemCount + '
'
+ '詳細' + itemCount + '
'
+ ' ';
}
}
30分くらいでざっとコーディングして提出
var button = document.querySelector('button'),
ul = document.getElementById('output'),
itemId = 0;
var itemTemplate = '';
var addCount = 10;
var output = document.getElementById("output");
function createItem() {
itemId++;
var item = new Object();
item.title = 'アイテム' + itemId;
item.detail = '詳細' + itemId;
return item;
}
function loadItemTemplate(item) {
var li = document.createElement('li');
var article = document.createElement('article');
var h1 = document.createElement('h1');
var p = document.createElement('p');
article.setAttribute('class', 'item');
h1.setAttribute('class', 'title');
p.setAttribute('class', 'detail');
h1.textContent = item.title;
p.textContent = item.detail;
article.appendChild(h1);
article.appendChild(p);
li.appendChild(article);
return li;
}
function addItems() {
for ( var i = 0; i < addCount; i++ ) {
itemTemplate = loadItemTemplate(createItem());
document.getElementById('output').appendChild(itemTemplate);
}
}
テンプレートのHTML生成がループしてるので無駄だなと思いつつ、この程度だと計測時間が変わらなかったのでとりあえず。
丁寧にアドバイスを頂きました。
var button = document.querySelector('button'),
ul = document.getElementById('output'),
itemId = 0;
var template;
var addCount = 10;
var li;
var article;
var h1;
var p;
loadItemTemplate();
function createItem() {
itemId++;
var item = new Object();
item.title = 'アイテム' + itemId;
item.detail = '詳細' + itemId;
return item;
}
function loadItemTemplate() {
template = document.createElement('li');
article = document.createElement('article');
h1 = document.createElement('h1');
p = document.createElement('p');
article.setAttribute('class', 'item');
h1.setAttribute('class', 'title');
p.setAttribute('class', 'detail');
article.appendChild(h1);
article.appendChild(p);
template.appendChild(article);
}
function bindItem(item) {
h1.textContent = item.title;
p.textContent = item.detail;
var itemRow = template.cloneNode(true);
ul.appendChild(itemRow);
}
function addItems() {
for ( var i = 0; i < addCount; i++ ) {
bindItem(createItem());
}
}
cloneNode()を利用してみたけど、なんかViewの分離がちょっと汚くなっちゃたかな? insertNode()とかを使って、ツリーを操作した方がスムーズなのかも。
「Leap Motion」を手に入れたのでXcodeで試してみた。
国内で買うと倍くらいしてしまうので、海外で買った方がお得で、意外と早く届きます(3日で届いた)。
https://www.leapmotion.com/setupから「Leap Motion Installer」をダウンロードして、インストールします。 非常にわかりやすいセットアップナビゲーションです。
アプリ管理は「AirSpace」で行います。 https://airspace.leapmotion.com/にアクセスすると、iTunesStore、GooglePlayのようにアプリが購入できます。 フリーのソフトもあるので、ざっと試す事ができます。
Leap Motionは、色々な言語に対応しているので自分の得意分野で開発かと思います。 (自分は XCode、Objective-Cで開発)
SDKは、https://developer.leapmotion.com/downloads からダウンロードできます。
ダウンロードしたSDKは、自分の管理しやすいパスに配置します。 ※自分は「/Users/ユーザ/leap/LeapSDK/」にしました
Xcode、Objective-Cで開発するにはいくつか準備が必要です。
(1) libLeap.dylib (2) Leap、LeapMathヘッダファイル (3) LeapObjectiveC
Cocoa Applicationでプロジェクト作成
ARCで作成してみる
「LeapSDK」のライブラリを利用するには、パスを通してやる必要があります。
まず、配置したLeapSDKのパス定義 ※「LEAPSDK_PATH」としました
headerファイルのパス定義 $(LEAPSDK_PATH)/inclulde
libraryファイルのパス定義 $(LEAPSDK_PATH)/lib
「Leap.h」「LeapMath.h」「LeapObjectiveC.h」「LeapObjectiveC.mm」をプロジェクトにドラッグ&ドロップ
「libLeap.dylib」をプロジェクトにドラッグ&ドロップ
Build Phasesで、ファイルが追加されるのを確認
メインプログラムは「LeapSDK/samples/Sample.cpp」をそのまま記述しました。
#import
#import "LeapObjectiveC.h"
@interface LeapTest : NSObject
- (void)run;
@end
「LeapObjectiveC.h」を読み込んで、「LeapListener」で拡張
#import "LeapTest.h"
@implementation LeapTest
{
LeapController *controller;
}
- (void)run
{
controller = [[LeapController alloc] init];
[controller addListener:self];
NSLog(@"running");
}
- (void)onInit:(NSNotification *)notification
{
NSLog(@"Initialized");
}
- (void)onConnect:(NSNotification *)notification
{
NSLog(@"Connected");
LeapController *aController = (LeapController *)[notification object];
[aController enableGesture:LEAP_GESTURE_TYPE_CIRCLE enable:YES];
[aController enableGesture:LEAP_GESTURE_TYPE_KEY_TAP enable:YES];
[aController enableGesture:LEAP_GESTURE_TYPE_SCREEN_TAP enable:YES];
[aController enableGesture:LEAP_GESTURE_TYPE_SWIPE enable:YES];
}
- (void)onDisconnect:(NSNotification *)notification
{
//Note: not dispatched when running in a debugger.
NSLog(@"Disconnected");
}
- (void)onExit:(NSNotification *)notification
{
NSLog(@"Exited");
}
- (void)onFrame:(NSNotification *)notification
{
LeapController *aController = (LeapController *)[notification object];
LeapFrame *frame = [aController frame:0];
NSLog(@"Frame id: %lld, timestamp: %lld, hands: %ld, fingers: %ld, tools: %ld, gestures: %ld",
[frame id], [frame timestamp], [[frame hands] count],
[[frame fingers] count], [[frame tools] count], [[frame gestures:nil] count]);
if ([[frame hands] count] != 0) {
LeapHand *hand = [[frame hands] objectAtIndex:0];
NSArray *fingers = [hand fingers];
if ([fingers count] != 0) {
LeapVector *avgPos = [[LeapVector alloc] init];
for (int i = 0; i < [fingers count]; i++) {
LeapFinger *finger = [fingers objectAtIndex:i];
avgPos = [avgPos plus:[finger tipPosition]];
}
avgPos = [avgPos divide:[fingers count]];
NSLog(@"Hand has %ld fingers, average finger tip position %@",
[fingers count], avgPos);
}
NSLog(@"Hand sphere radius: %f mm, palm position: %@",
[hand sphereRadius], [hand palmPosition]);
const LeapVector *normal = [hand palmNormal];
const LeapVector *direction = [hand direction];
NSLog(@"Hand pitch: %f degrees, roll: %f degrees, yaw: %f degrees\n",
[direction pitch] * LEAP_RAD_TO_DEG,
[normal roll] * LEAP_RAD_TO_DEG,
[direction yaw] * LEAP_RAD_TO_DEG);
}
NSArray *gestures = [frame gestures:nil];
for (int g = 0; g < [gestures count]; g++) {
LeapGesture *gesture = [gestures objectAtIndex:g];
switch (gesture.type) {
case LEAP_GESTURE_TYPE_CIRCLE: {
LeapCircleGesture *circleGesture = (LeapCircleGesture *)gesture;
NSString *clockwiseness;
if ([[[circleGesture pointable] direction] angleTo:[circleGesture normal]] <= LEAP_PI/4) {
clockwiseness = @"clockwise";
} else {
clockwiseness = @"counterclockwise";
}
float sweptAngle = 0;
if(circleGesture.state != LEAP_GESTURE_STATE_START) {
LeapCircleGesture *previousUpdate = (LeapCircleGesture *)[[aController frame:1] gesture:gesture.id];
sweptAngle = (circleGesture.progress - previousUpdate.progress) * 2 * LEAP_PI;
}
NSLog(@"Circle id: %d, %@, progress: %f, radius %f, angle: %f degrees %@",
circleGesture.id, [LeapTest stringForState:gesture.state],
circleGesture.progress, circleGesture.radius,
sweptAngle * LEAP_RAD_TO_DEG, clockwiseness);
break;
}
case LEAP_GESTURE_TYPE_SWIPE: {
LeapSwipeGesture *swipeGesture = (LeapSwipeGesture *)gesture;
NSLog(@"Swipe id: %d, %@, position: %@, direction: %@, speed: %f",
swipeGesture.id, [LeapTest stringForState:swipeGesture.state],
swipeGesture.position, swipeGesture.direction, swipeGesture.speed);
break;
}
case LEAP_GESTURE_TYPE_KEY_TAP: {
LeapKeyTapGesture *keyTapGesture = (LeapKeyTapGesture *)gesture;
NSLog(@"Key Tap id: %d, %@, position: %@, direction: %@",
keyTapGesture.id, [LeapTest stringForState:keyTapGesture.state],
keyTapGesture.position, keyTapGesture.direction);
break;
}
case LEAP_GESTURE_TYPE_SCREEN_TAP: {
LeapScreenTapGesture *screenTapGesture = (LeapScreenTapGesture *)gesture;
NSLog(@"Screen Tap id: %d, %@, position: %@, direction: %@",
screenTapGesture.id, [LeapTest stringForState:screenTapGesture.state],
screenTapGesture.position, screenTapGesture.direction);
break;
}
default:
NSLog(@"Unknown gesture type");
break;
}
}
if (([[frame hands] count] > 0) || [[frame gestures:nil] count] > 0) {
NSLog(@" ");
}
}
- (void)onFocusGained:(NSNotification *)notification
{
NSLog(@"Focus Gained");
}
- (void)onFocusLost:(NSNotification *)notification
{
NSLog(@"Focus Lost");
}
+ (NSString *)stringForState:(LeapGestureState)state
{
switch (state) {
case LEAP_GESTURE_STATE_INVALID:
return @"STATE_INVALID";
case LEAP_GESTURE_STATE_START:
return @"STATE_START";
case LEAP_GESTURE_STATE_UPDATE:
return @"STATE_UPDATED";
case LEAP_GESTURE_STATE_STOP:
return @"STATE_STOP";
default:
return @"STATE_INVALID";
}
}
@end
サイクルは以下の種類があり、NSNotificationで検知して処理するようです。
ジェスチャーはonFrame()で主に処理してやる必要がありますが、普通に書いてしまうと分岐の嵐になりそうですね。
最後に、AppDelegateでメインプログラムを処理します。 ※ARCで書いたので「LeapTest.h」は@classでなくimportにしています
#import
#import "LeapTest.h"
@interface AppDelegate : NSObject
@property (assign) IBOutlet NSWindow *window;
@property (nonatomic)LeapTest *leapTest;
@end
#import "AppDelegate.h"
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
_leapTest = [[LeapTest alloc]init];
[_leapTest run];
}
@end
ビルドして動かすと、ジェスチャーとともにログが変化するのが確認できます。
と、とりあず動作確認程度ですが、ここからが大変そうですね。
「crontab -e」でpicoとかのエディタが開いてしまう場合、「.bashrc」にviのパスを通してやる。
export EDITOR=/usr/bin/vi
OSX上にVirtualBoxでLinuxを利用してる場合、VirtualBoxのイメージバックアップもいいですけど、結構時間がかかって面倒だったりします。
ローカル内なら、日常的ディレクトリバックアップは、やっぱりrsyncが便利かな?と。 OS自体はVirtualBoxの再セットアップ自体はそんなに時間かからないし。 と言う事で、大事なデータだけSSH経由でrsyncバックアップをすることに。
rsyncはコマンドなので、SSHを経由する場合は自動認証が必要です。
ssh-keygen -t rsa
秘密鍵:id_dsa 公開鍵:id_dsa.pub
作成した公開鍵「id_dsa.pub」を「authrized_keys」で、バックアップ元の「.ssh/」に配置する。 複数のキーでアクセスする場合は、authrized_keysに公開鍵を行毎にコピー&ペーストで動作します。
rsyncは、色々オプションがありますが今回は簡易的に「アーカイブモード(-a)」「途中経過(-v)」だけ設定します。
rsync -av -e ssh /home/yoo/ yoo@192.168.1.51:/Users/yoo/Debian/
あとはcronとかで定期実行すれば、差し当たりのバックアップは作成できます。