Quantcast
Channel: その後のその後
Viewing all 317 articles
Browse latest View live

[iOS][Objective-C][Swift][WWDC]Objective-C で書いたアプリを Swift で書き換える5ステップ

$
0
0

iBookでSwiftの解説本出ましたが、言語自体にはそれほど興味がないので、実践的なところとして、手始めに「Objective-Cで書いた既存アプリをSwiftで書き換える」ところからやってみました。


アプリ全体、となると壮大なテーマになってしまうので、まずは AppDelegate だけ書き換えてみます。


なお、NDA 下にある Xcode 6 については書けないので、ビルド設定等については割愛しています。


1. 拡張子を .swift にする

例えば AppDelegate.m なら、AppDeleagate.swift にします。


2. import の書き換え

ヘッダの import も移してきて、

#import <UIKit/UIKit.h>

だったのを

import UIKit

にします。


3. クラス宣言の書き換え

これもヘッダから移してきて *1

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@end

だったのを、

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
}

にします。


ただし

@UIApplicationMain

は AppDelegate.swift の場合のみ。


また上記のプロパティ宣言部分

var window: UIWindow?

にある `?` は、 nilを許容するかどうか を明示的に指定するものです。


4. メソッド定義の書き換え

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    return YES;
}

だったのを、

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
    // Override point for customization after application launch.
    return true
}

にします。


どこがどう書き換わっているかは、上記の例で一目瞭然で、説明不要かと思います。


5. main.mを削除

あまりいじる機会の少ない main.m では、

int main(int argc, char * argv[]) {
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

と、UIApplicationMain 関数に AppDelegate のクラスを渡していました。


Swift では上述したように AppDelegate.swift に同等のことを書いてしまってるので、main.m は不要となるので削除してしまいます。



以上の手順で(とくに中身のないAppDelegateの場合は)ビルドが通って動作するようになります。


おわりに

冒頭で「言語自体にはあまり興味がない」と書きましたが、Swiftのお試しがてらこれをやってみると、Objective-C と Swift の違いがよくわかり、「なるほど、このあたりのおかげで LLVM がグッと最適化できて高速化につながってるのか」と勉強になりました。

*1:実装ファイルに無名カテゴリで宣言しているメンバ変数やプロパティがあればそれもマージすることになるかと。


[iOS][Core Bluetooth][デバイス連携]BLEデバイスと連携するiOSアプリ開発での「落とし穴」についてWWDCラボで聞いてみました

$
0
0

Core Bluetooth / Bluetooth Low Energy で iOS アプリと連携する新規ハードウェアを開発したことのある人にとってはあるあるな話だと思うのですが、開発途中でペリフェラル側(外部デバイス)で GATT の内容を変更すると、iPhone の Settings から Bluetooth を Off/On しないと変更が反映されない、というのがあります。


このことを知らないと、

  • キャラクタリスティックの `value` が取れない
  • -> BLE の接続状態を疑う
  • -> Central / Peripheral 間での UUID の食い違いを疑う
  • etc...

と、無駄なデバッグ作業をしてしまいかねません。


下記スライドでも最後の方のページで「ハマりどころ」として紹介されています。


しかし例えばデバイス側の GATT に Characteristic をひとつ追加したとして、リリース済みサービスの場合、エンドユーザーに Off/On してもらうっておかしくない?と思い、せっかくなので現在絶賛参加中の WWDC 2014 の "Accessories and I/O Technologies Lab" で質問してみました。


Appleの公式回答

質問してみると、「あーー Cache の件ね!」とすぐに質問の意図を理解してもらえたので、やはりあるあるケースなようです。


で、まずは Bluetooth.org の Core Specifications を見よう、と。


f:id:shu223:20140605041045p:image:w300


Core Specifications は下記ページより ダウンロードできます。


目次をみると1351ページ以上(!)もあるPDFなのですが、その「7.1 SERVICE CHANGED」という項目があるので、そこを読めと。


どうやら、サービスに変更があった場合に使うキャラクタリスティック "Service Changed" が標準で定義されているのでそれを使えばいいよ、ということらしいです。


なるほど、となったところで「そういうことだから、じゃ!」となりそうだったので、ちょっと待って、iOS側はそのキャラクタリスティックに対してどうしたらいいの、 勝手にキャッシュクリアしてくれるの?それともアプリ内で明示的に何らかの処理をする必要があるの? ということを聞いたところ、


デバイス側で上述したキャラクタリスティックをGATTに追加しておいて必要に応じてサービス変更を通知すると、


CBPeripheralDelegate の `peripheral:didModifyServices:` が呼ばれる


ので、そこで再度 `discoverServices:` すればOKとのこと。


余談:ラボ初体験記

WWDCは今回が初参加で、「セッションは動画がすぐに公開されるので行かなくてよい、WWDCはラボで質問しまくってこそ価値がある!」と聞いてたので、「ラボで何か聞かないと・・・でも不安だ・・・」(英語コミュニケーション的な意味で)とプレッシャーを感じていました。


でもBLEについて聞けそうなラボはそんなにないので今いくしかない!と部屋に入ったものの、

といったんは逃げ帰りました。


ランチ後、「今年はiOS8のセッション聞きたいし別にラボはいいかな。。」と日和りそうになったものの


というわけで質問を全文考えていくことで乗り切ることができました。


あと、事前に @u_akihiro さんが Service Changed キャラクタリスティックの存在を教えてくださっていたので、回答が理解できたというのもあります。(いつもありがとうございます!)



これでもうWWDCの残りを気楽に楽しめます。めでたしめでたし。


[iOS][Objective-C][Swift][Xcode]開発者向け公開情報から見る iOS 8 の細かい新機能8つ

$
0
0

今まさに開催中のWWDC2014では、Swift、HealthKit、HomeKit、Metal、Extensions とキーノートでは言語レベル、新規フレームワークレベルでの大きな新機能について発表されましたが、従来フレームワークにもいろいろと有用な機能が追加されています。


例年のWWDCではそれらはNDA下にあり正式リリースまで話題にすることはできなかったのですが、今年はAppleがいろいろと情報を公開してくれている(ログイン不要で見れるようになっている)ので、それらの情報リソースから、「これは嬉しい」と思った機能をいくつか挙げていきます。


※Xcode 6 はNDA下にあるため、実行結果には言及しないようにしています。


UIVisualEffectView

クラスリファレンスを見ると、

- (instancetype)initWithEffect:(UIVisualEffect *)effect

というメソッドで初期化でき、UIVisualEffect 型のオブジェクトを渡せるようになっています。


UIVisualEffectを継承するクラスとしては

  • UIBlurEffect
  • UIVibrancyEffect

の2つが用意されています。


ここで注目すべきは UIBlurEffect 。


UIナントカView にブラーエフェクトを渡せる、というのはまさにあの「磨りガラス効果」ではないでしょうか。


iOS7で導入されキーノートのときから目を引いていたエフェクトだったものの、その実装方法には諸説あったので、やっと磨りガラス論争に終止符が打たれそうです。


CIKernel

Core Image の更新。カーネルというのはフィルタをかける際に、畳み込み演算する核となるマトリックスのことで、これがAPIとして出てきたということは、事実上 iOS でもカスタムフィルタの作成が可能となったと言えると思います。


What's New in iOS でも触れられています。

You can create custom image kernels in iOS.


残念ながらまだクラスリファレンスは公開されていません(2014.5.4現在)。


関連記事

AVAudioEngine

iOS の Core Audio においてもっとも低レイヤに位置し、リアルタイムで高度なオーディオ波形処理や、複雑なルーティングによるオーディオ処理を実現することができる Audio Unit というのが従来からあったのですが、これらは AVFoundation 等に比べると少々複雑で、しかもAPIがC言語タイプなので、自分のようなゆとりiOSエンジニアには少しハードルが高い部分がありました。

iOS 8 で追加された AVAudioEngine は、その API をみると、完全に Audio Unit の Objective-C ラッパーな感じで、上記のAudio Unitのハードルの高さを解消してくれているのでは、という期待ができます。


ギターのエフェクターのようにユニットを繋げる楽しさも健在で、たとえば AVAudioUnitEffect を継承するクラスとしては、

  • AVAudioUnitDelay
  • AVAudioUnitDistortion
  • AVAudioUnitEQ
  • AVAudioUnitReverb

といったものが用意されています。


CLFloor

公開されているクラスリファレンスを見ると、

A CLFloor object specifies the floor of the building on which the user is located.

とあり、`level` (read-only) というプロパティが定義されています。


地図からフロア情報も取得できるようになるのではないでしょうか。


CLVisit

クラスリファレンスによると、ユーザーの過去の訪問履歴を扱うためのクラスのようです。

  • coordinate
  • horizontalAccuracy
  • arrivalDate
  • departureDate

といったプロパティを持っています。


そして、"CLLocationManager+CLVisitExtensions.h" という CLLocationManager のカテゴリが追加されていて、

func startMonitoringVisits()
func stopMonitoringVisits()

というメソッドが使えるようになっています。


また、CLLocationManagerDelegate に、次のデリゲートメソッドが追加されています。

@optional func locationManager(_ manager: CLLocationManager!,
                      didVisit visit: CLVisit!)

で、What's newを見ると、

The visit service provides an alternative to the significant location change service for apps that need location information about interesting places visited by the user.

とあり、バックグラウンドで位置情報をとるためにこれまで用いていた significant location のしくみ(GPSではなく基地局ベースのやつですね)に代わり、訪れた場所をモニタリングするサービスのようです。


Manual Camera Controls

関連メソッドが多いので詳細は省略しますが(API Diffsから確認できます)、カメラの

  • フォーカス
  • ホワイトバランス
  • 露出

の設定が直接制御できるようになっています。


Accelerate Framework

従来からあるフレームワークですが、大量のクラス/メソッドが追加されています。API Diffs のページ面積の約半分(!)近くを占めるほどです。


高速画像処理演算ライブラリの vImage、線形代数演算等が強化されています。


IBでのカスタムフォントプレビュー

What's New in Xcode によると、

Custom iOS fonts. Interface Builder renders embedded custom fonts during design time, giving a more accurate preview of how the finished app will look, with correct dimensions.

とあります。カスタムフォントを Interface Builder で選べてプレビューできる、ということです。


これは個人的には待望の機能で、つい先日

という記事を書いて有料のプラグインを紹介したばかりなのですが、標準でサポートしてくれるに越したことはない *1 ので、ありがたい機能追加です。

*1:サードパーティ製有料プラグインを使うと、たとえばチームでプロジェクトを共有するときに困る

[iOS][Objective-C]【iOS8】App Extension の実装方法 その1:Action

$
0
0

App Extension とは?

App Extension (Extensions) は、iOS 8 から導入される、新しいアプリ間連携のしくみです。


f:id:shu223:20140606094505p:image


iOS では、以下の 6種類の Extension point *1を利用することができます。

  • Today
  • Share
  • Action
  • Photo Editing
  • Storage Provider
  • Custom keyboard

大まかな仕組みは同じなのですが、見た目/機能は Extension point によって色々と違いがあり、実装方法も違ってくる(部分もある)ので、個別に説明していきたいと思います。


まずは一番説明しやすい "Action" から。


1. ターゲットを作成する

Xcode の [File] > [New] > [Target] から、[Application Extension] > [Action Extension] を選択します。


f:id:shu223:20140606093345j:image

(※Xcode6のスクショではありません。App Extension Programming Guide の図3-1 です。)


ここでは [Action Type] は [View Controller] を選択します。


2. Extension の実装

Extension が起動されたときの見た目や挙動を実装します。


たとえば、ImageInverter サンプルでは、`viewDidLoad` で入力画像を反転して表示するように実装されています。

// extensionContextから入力アイテムを取得
NSExtensionItem *imageItem = [self.extensionContext.inputItems firstObject];

// NSItemProviderを取得
NSItemProvider *imageItemProvider = [[imageItem attachments] firstObject];

if([imageItemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeImage]){

    // 入力画像を取得    
    [imageItemProvider loadItemForTypeIdentifier:(NSString *)kUTTypeImage options:nil completionHandler:^(UIImage *image, NSError *error) {
        
        if(image){
            
            dispatch_async(dispatch_get_main_queue(), ^{
                
                // 画像を反転させる
                UIImage* invertedImage = [self invertedImage:image];
                
                // 表示
                [imageView setImage:invertedImage];
            });
            
        }
    }];
    
}

(説明用に簡略化しています。また `invertedImage` メソッドのソースは省略。)



そして、done ボタン押下で編集済みアイテムを返します。

-(void)done:(id)sender{
    
    // 編集済みのNSExtensionItemオブジェクトを作成
    NSExtensionItem *extensionItem = [[NSExtensionItem alloc] init];
    [extensionItem setAttachments:@[[[NSItemProvider alloc] initWithItem:[self.imageView image]
                                                          typeIdentifier:(NSString*)kUTTypeImage]]];
    
    // Host appに返す
    [self.extensionContext completeRequestReturningItems:@[extensionItem] completionHandler:nil];
}

Host appの実装

Extension を呼び出す側のアプリの実装です。


ボタン押下時に UIActivityViewController を表示する、というのは従来と同じなのですが、完了ハンドラの引数で、Extention から返ってきたアイテムを受け取れるようになっています。


ImageInverter サンプルでは、下記のように画像を取り出して表示しています。

- (IBAction)share:(id)sender {
    
    UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:
  @[[self.imageView image]]
                                                                                         applicationActivities:nil];
    
    [activityViewController setCompletionWithItemsHandler:^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError * error){
        
        // 返ってきたアイテムを取得
        NSExtensionItem* extensionItem = [returnedItems firstObject];
        NSItemProvider* imageItemProvider = [[extensionItem attachments] firstObject];

        // 画像を取り出して表示
        if([imageItemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeImage]){
            
            [imageItemProvider loadItemForTypeIdentifier:(NSString *)kUTTypeImage
                                                 options:nil
                                       completionHandler:^(UIImage *item, NSError *error) {
                                           
                                           if(item && !error){
                                               
                                               dispatch_async(dispatch_get_main_queue(), ^{
                                                   [self.imageView setImage:item];
                                               });
                                           }
                                       }];
        }
    }];
    
    [self presentViewController:activityViewController animated:YES completion:nil];
}

(説明用に簡略化しています。)


実行時の注意点

新しい機能なので、 UIActivityViewController が立ち上がってどうすればいいか一瞬戸惑うのですが、初回のみ [More] から今回追加した Extension を有効にして、UIActivityViewController を立ち上げ直す必要があります。


InvertImageサンプル自体は公開されているものの、Xcode6はNDA下にあるため、実行結果のスクショはここでは掲載を控えておきます。


参考資料

本記事は、以下のAppleによる公開リソースをもとに作成しています。


*1:OS X は4種類

[iOS][Xcode]【iOS8】HealthKit の Apple 公式サンプルを実機で動作させようとすると出るエラーの対処方法

$
0
0

アップルが公開している HealthKit のサンプル をビルドして実機にインストールしようとすると、


The excutable was signed with invalid entitlements.


というエラーが出てアプリが起動しません(2014年6月10日現在)。


この対処方法について、WWDCのラボで聞いてきました。

  • iOS Dev Center で プロファイルを作り直す
  • Bundle IDを新しいプロファイルに合わせて変更する
  • entitlements.plist の application-identifier の項を削除する

以上の手順で実機でも動作するようになりました。


プロファイルを作り直すときに、 使用する Identifier の HealthKit を Enabled にする のが最大のポイントです。


[iOS][雑記]NDAについて、WWDCでAppleの中の人に聞いてみました

$
0
0

今年のWWDCでは例年に比べ Apple自身が公開してくれている情報 が多く、実質的にNDAが緩くなったといえます。


Appleが公開しているサンプルコードについてWWDCのラボで聞いてみた 際に、「今教えてくれたこと、ブログとかに書いていいんでしょうか?」と質問すると、次のような回答をくれました。


1. iOS Dev Center にログインする

2. Member Center に行く

3. [Your Account] > [Legal Agreements] > [iOS Developer Program License Agreement] を開く

4. "WWDC" で検索する (-> 10.1 Information Deemed Apple Confidential が引っかかる)

5. そこを読んでお前の弁護士と相談しろ


なるほど、すごく明快な回答です。WWDCに限らず、結局こういう系の話はこういう答えになるんだなと。


[雑記][海外就職][iOS]WWDC2014の旅 15泊17日を振り返る

$
0
0

まだサンフランシスコにいるのですが、もう帰る以外の予定はないので、遅ればせながら「WWDC2014の旅」を振り返ってみます。


旅程

シリコンバレーを訪れるのは、昨年9月に すぐにまた戻るつもりで帰国 して以来、結局一度も戻らなかったので実に 9ヵ月ぶり


せっかくなので他にもいろいろやっていこうということで、下記のようにWWDCの前後に6日間ずつの余裕を持たせた旅程にしました。

  • 5/27 日本発
  • 6/2〜6/6 WWDC
  • 6/12 日本着

やったこと

(WWDCに参加する以外には)特に具体的な予定がなかったのですが、知り合い繋がりでオフィスに遊びに行ったり、偶然街でバッタリ会ったりとかで、なんだかんだと充実した旅になりました。かまってくれた皆様どうもありがとうございました!


WHILL HQ訪問

TechShopという、FabLabの超でっかい版みたいな場所があり、そこにWHILLが米国オフィス(つまりHQ)を構えています。そこにお邪魔してきました。


f:id:shu223:20140610113419j:image:w400

(WHILL榊原さんの仕事風景)


TechShopには、3Dプリンタや3Dスキャナ、A0プリンタ、レーザーカッター等の定番マシンはもちろんのこと、


鉄を工作するための諸々の大型機械や、

f:id:shu223:20140610120007j:image:w600


木工用の大型機械、溶接するための台(?)、フォークリフトまであります。

f:id:shu223:20140610120144j:image:w600


ジャンク品コーナーや、無料ネジコーナーも。

f:id:shu223:20140610113811j:image:w400


いろいろと作業や打ち合わせもあり、今回の滞在中に3回お邪魔しました。


とあるベンチャーのアメリカ支部訪問

某有名Webサービスを運営する企業のアメリカ支部にお邪魔しました。(まだあまり情報公開したくないそうなので写真や場所について書くことは控えます)


オフィスもプロダクトももの凄く素敵で、技術的にも面白く、かなり刺激を受けました。


Kinoma 訪問

Kinoma Create を開発する Kinoma のオフィスにもお邪魔しました。


f:id:shu223:20140610114005j:image:w400

(逆光で見えづらいですが素敵なオフィスです)


開発中の Kinoma Create 実機やシミュレータ、コードなども見せていただきました。


f:id:shu223:20140610114047j:image:w400


f:id:shu223:20140610114158j:image:w400

(裏のピンにセンサを自由に追加できる)


f:id:shu223:20140610114157j:image:w400

(表にもピンが 8 x 2列あり、それぞれの役割をモニタから変更できる)


f:id:shu223:20140610114155j:image:w400

(シミュレータも用意されているので、デバイスが手元になくてもコーディング&テスト可能)


Indiegogo での注文分については 9月頃配送開始とのこと。一般発売が楽しみです!


お宅訪問

ぶらぶら散歩してたら知り合いの日本人エンジニア(バスケさん)と偶然遭遇!その辺りに住んでることも知らなかったので、お互い相当ビックリしました。


そしてそのままお宅訪問。


f:id:shu223:20140610114736j:image:w400


ちょうど引っ越しされる数日前で、「引っ越しの手伝い」という名の飲み会に参加させていただきました。


もくもく開発

とくに予定がない週末はカヤック時代の後輩 おかず と、Workshop Cafe でもくもく作業してました。


場所は BART の Montgomery 駅の近く。電源、WiFiがあり、しかも長居しやすいので、開発などに没頭したい場合にはおすすめです。


WWDC2014

初めて参加したわけですが、いやー 楽しかったですね。iOSのメジャーアップデートが発表されて、そりゃ開発者としてはできることが増えて嬉しいし、そういう情報を真っ先に聞ける、Appleの開発者に直接聞けるというメリットもありますが、それよりも何よりも、このプラットフォームでご飯食べてる人たちが世界中から集まってきてワイワイやってる、その空気感がたまらなく楽しかったです。


f:id:shu223:20140610114351j:image:w400

(あこがれのあのジャケットをもらいその場で記念撮影)


f:id:shu223:20140610114421j:image:w400

(早朝3時から基調講演の行列に並ぶ。いろんな人が暇つぶしにしゃべりにくるので、これがすごく楽しい)


f:id:shu223:20140610114418j:image:w400

(基調講演。3時から並んだわりにはわりと遠いw)


f:id:shu223:20140610114419j:image:w400

スペインに行ったときに会った Marcos がなんとアップルの中の人になってて再会!!!!一緒にランチ。)



技術情報的なところでは、既にいくつかブログに書いてるので、そちらもぜひ。


泊まったところ

Mission District

WWDCが始まるまでは、行ったことのないエリアに住んでみよう、とAirbnbで見つけたミッション地区のアパートに住んでみました。



閑静な住宅街で、AppleやFacebookの人たちも大勢このあたりに住んでいるそうです。(このあたりからクパチーノ行きのApple社員専用通勤バスが出ているとのこと)


WWDC会場近辺

近辺、といっても徒歩15分ちょいかかりますが、1泊90ドルで、WiFiも快適に繋がってなかなかいいホテルでした。



WWDCの期間+前後2日ずつで合計9日間滞在。


TechHouse

日本人が運営するシェアハウス。ここを運営されている長谷川さんと食事する機会があり、WWDC閉幕後の数日間はまだ宿を決めてなかったのでお世話になることに。

場所はBARTの Balboa Park 駅から徒歩で約12分のところにあります。



掃除が行き届いていて、すごくきれいで快適でした。


f:id:shu223:20140610114154j:image:w400


で、お値段がなんと1泊30ドル!Airbnbだと同じスペックで80ドルはするんじゃないかと。中心街までBARTですぐだし、とてもおすすめです。


費用

  • 飛行機代:¥126,850
  • WWDCチケット代:¥158,800
  • 宿代1:¥42,556
  • 宿代2:$720
  • 宿代3:$90

これだけで既に40万円オーバー。計算してませんが、上記プラス滞在中の食事やら電車賃も合計数万ぐらいはかかってるんじゃないかと思うと、なかなかの出費です。


さらに自分はフリーランスなので、仕事をしてない間は収入も止まります。その機会損失分も加味すると・・・


まとめ

  • 初のWWDC、行く前は不安だったけどめちゃくちゃ楽しかった
    • 心配してた英語は全然問題にならなかった。ラボで質問して聞き取れなかったらGoogle翻訳引っ張りだしてまで説明してくれた
  • WWDC以外の日々も充実してた。旅程を長めにとってよかった
  • こっちで会った何人かの「フルスタックエンジニア」は、サーバーサイド、iOS、Android、JSとかだけじゃなく、電子回路やファームウェア等のデバイス側もカバーしてて、もっともっと精進せねばと気が引き締まった
  • お金はかかるしWWDC情報なら日本で十分得られるけどこういう生の経験や交流はプライスレス。来年もチケット当選したらぜひ行きたい

現地でお世話になった皆様ありがとうございました!


[Mac][ツール]Markdownでプレゼン用スライドをつくる方法いろいろ

$
0
0

明日は 「yidev第十五回勉強会」、来週はクックパッドさん主催の 「WWDC2014 振り返り勉強会」で発表をさせていただく *1 のですが、まずMarkdownで話そうと思うことを適当にメモしてるうちに、なんか発表資料このままで良くない?と思えてきました。別にレイアウトや配色のセンスに自信があるわけでもなし


で、最初 "markdown pagination" でググってみるとあまりパッとしたのがなかったのですが、"markdown presentation" にしてみると出るわ出るわ。しかもどれも結構よさげ。


というわけで出てきたものをメモがてら書き留めておきます。結論からいうとググって一番上に出てきた "Remark" が今回の要件に(ほぼ)マッチしていたので、他はまだ使ってません。


Remark

http://remarkjs.com/

  • GitHubでソース公開されてて気軽に使える
    • 無料
    • ログイン不要
    • 不満があれば自分で修正してpull request送れる
  • Markdown が html ファイル内にあるので、Markdown エディタで編集しづらい

Swipe

http://beta.swipe.to/markdown/

  • テンプレートやフォントが複数用意されてる(っぽい)
  • 要ログイン
    • スライドを公開したい場合には長所でもある

Docset

http://www.decksetapp.com/

  • Mac アプリ
  • 19.99ドル

Reveal.js

https://github.com/hakimel/reveal.js/

  • HTMLやMarkdown等、テキストベースのスライドをつくれる
  • たぶんこの中では一番メジャー。日本語での紹介記事もたくさん出てる

Slidify

http://slidify.org/

  • サイトが10ブックマークされてるので国内でちょっと話題になったことがある?

*1:発表内容は使い回しではなく、どちらも全く別々の話をする予定です


[参考書籍][iOS][Objective-C][Xcode]【書評】中級者向けのUIKit解説本『UIKit徹底解説』

$
0
0

インプレスジャパン様より *1 献本いただきました。


UIKit徹底解説 iOSユーザーインターフェイスの開発
西方 夏子
インプレスジャパン
売り上げランキング: 8,651

著者の西方夏子さんは、『上を目指すプログラマーのためのiPhoneアプリ開発テクニック iOS 7編』の

  • Chapter02:「画面遷移」
  • Chapter03:「UIKit Dynamics」

等々を執筆されていた方で、僕も iOS 7 から入った「カスタム画面遷移」「インタラクティブ画面遷移」はこの書籍のサンプルで勉強させていただきました。*2


ブログの記事も書籍のように詳しくわかりやすく、いつも参考にさせていただいています。



で、今回の『UIKit徹底解説』ですが、中級者向けUIKit専門書とのこと。UIKitはiOSアプリ開発の主役なので解説書こそ多いものの、中級者以上を対象としたものはあまりないので、ありがたく拝読させていただきました。


難易度について

実際に読んでみて、難易度の点では、わりと「脱初級した人」ぐらいから読んでも大丈夫かも、という印象を持ちました。


たとえば Auto Layout の章で言うと、制約の優先度についてかなり詳しく書いてある部分は中級者向けだなと思う一方、IB から Auto Layout 設定する方法についてはスクリーンキャプチャ付きで書いてあるので、「Auto Layout をこれから使う人」にも読めるかなと。全体的に IB を使う部分は最初の一歩目としても大丈夫そうです。


またChapter10〜12は、それぞれテーブルビュー、コレクションビュー、コンテナビューコントローラの使い方/つくりかたをチュートリアル形式でちょっとずつ応用を加えながら学べるようになっているので、プログラムの話を文章だけ読んでもよくわからん、という方にはこの辺りからやってみるといいのかなと。


勉強になった項目

以下、勉強になった項目を書いていきます。

ライフサイクル

ライフサイクルについて、

  • Storyboardを使ってる場合はどうなるか
  • それぞれのメソッドにおいてsuperは呼ぶべきなのかどうか
    • たとえば loadView をオーバーライドする場合は super のは呼び出さず、すべてのビューを自前で生成することが推奨されているとのこと

等々を再確認できました。


あと、知らなかったのが isMovingToParentViewController というプロパティ。viewWillAppear や viewDidAppear が呼ばれるタイミングで、なぜコンテナに追加されたのかを知ることができる、とのこと。つまり、push されてここに来たのか、pop されて来たのかがわかるということ(そうは書いてないけど、そう理解しました)。これはありがたい。

レイアウト

iOS 7 が出たときに誰もが経験したと思われる、UINavigationBar の下にビューが潜り込む問題。対症療法的なものや微妙に誤解のある解説などWebには玉石混淆の情報が入り乱れていましたが、こちらの書籍ではフルスクリーンレイアウトについて関連プロパティがひとつひとつ解説されていて、正しく理解することができます。


またサブビューの再レイアウト処理の順序も勉強になりました。

  • Auto Layout無効のときの AutosizingMask に応じた自動サイズ調整処理は viewWillLayoutSubviews より前に行われる
  • layoutSubviews は viewWillLayoutSubviews の後、viewDidLayoutSubviews の前に呼ばれる

とか。

UIFontDescriptor

フォント属性を管理するクラス、UIFontDescriptor について詳細に解説されています。

  • フォントにアフィン変換を適用できる UIFontDescriptorMatrixAttribute
  • カスケードリストを追加して日本語だけ別フォントを使う方法
  • グリフの送り幅の変更

等々、参考になりました。

NSAttributedString, Text Kit

この2つについてもかなり詳しく書かれています。テキストレイアウトまわりで何かやりたいときにリファレンスとして良さそうです。


その他

上記には挙げていませんが、Stroryboard や Auto Layout や UIAppearance や UICollectionView や画面遷移等々、UIKit 全般について基本的なことから細かい話まで書かれています。詳細な目次はこちらで確認できます。


僕は インプレスジャパン発行の iOS 解説書シリーズは全部買ってる ので「Storyboardはあの本も詳しかったな」「UIAppearanceはあの本でも一通り解説されてたな」とか思ってしまうのですが、まだそういった書籍を揃えてない方にはこの本が全部入りかつ最新情報なのでお得なんじゃないかと思います。


電子書籍版

ちなみに国内出版社の技術書としては珍しく(?)もう電子版も出ています。700円ほどお得ですし、448ページと物量もあるので、個人的にはこちら(電子書籍)がオススメです。


UIKit徹底解説 iOSユーザーインターフェイスの開発
インプレスジャパン (2014-06-18)
売り上げランキング: 9,219

関連記事


*1@hkato さんより打診いただきました。いつもありがとうございます!

*2:カスタム画面遷移についてはこちらのサンプルもご参照ください:『【iOS7】53種類のカスタム画面遷移を試せるサンプルコードを公開しました - Over&Out その後

[iOS][デバイス連携][ガジェット][Bluetooth]【iOS8】いますぐ試せる HealthKit & HomeKit

$
0
0

iOS 8 の新機能の中でも個人的に気になったのが HomeKit と HealthKit。でも何ができるのか、実際どうやって使うのか、どこまでAPIが開発者に公開されてるのか、発表だけ聞いてもいまいちピンと来ません。


実際に自分で試してみるのが一番です。


そんなわけで、HealthKit、HomeKit を対応デバイスなしでいますぐ試す方法 について6/14日に開催された yidev 第15回勉強会で、表題の内容で発表してきました。


スライドはアップしないつもりだったのでKeynoteではなく Markdown でスライドをつくった のですが、世間的にWWDCの動画(今年のは一般公開されてる)ぐらいまでなら全然OKだよねっていう雰囲気っぽいのでここに内容を貼り付けておきます。


自己紹介

  • フリーランスiOSデベロッパー
  • ブログ:Over&Out その後
  • 著書:iOSアプリ開発 達人のレシピ100


HealthKit

HealthKit でできること

  • 健康、運動データの保存、アクセス
  • セキュリティ、プライバシー設定
  • 検索、統計クエリ
  • 単位変換
  • 新データの通知
  • アクセサリーの統合

とりあえずデバイス繋いで使ってみる

HealthKit デバイスの接続方法

  • APIを探しても見当たらない
  • WWDCセッション動画 "Introducing HealthKit"を見ても見当たらない

iOS8に標準で付いてくる "Health" アプリを利用する


f:id:shu223:20140623070334p:image:w300


対応デバイスを用意する

HealthKit 対応デバイス

"HealthKit対応"を謳ったものは当然まだない


→ BLEの標準プロファイルをサポートしてるので既存デバイスで普通に繋がる

  • Heart Rate Monitor
  • Glucose Sensor
  • Blood Pressure Monitor
  • Health Thermometer

対応デバイスを買いたくない

わりと高い。。


対応デバイスを代用する

iPhoneでエミュレートする
  • Core Bluetooth で実装する
  • アプリを使用する(例:LightBlue)
BLEモジュールにファームを書き込む
  • 例:BLE113 Development Kit

参考:BLE112 / 113 の開発環境を Mac に構築する - Over&Out その後


デモ


公式サンプル "Fit" のビルド方法

【iOS8】HealthKit の Apple 公式サンプルを実機で動作させようとすると出るエラーの対処方法 - Over&Out その後


参考資料

動画
  • Designing Accessories for iOS and OS X (701)
  • Introducing HealthKit (203)
Dev Center
  • HealthKitのサンプルコード
  • クラスリファレンスはまだない

HomeKit

HomeKitとは?

  • 各種アクセサリを独自のプロトコルで統一する
    • アクセサリ:鍵、照明、カメラ、ドア、サーモスタットetc...
  • ユーザ別にデバイスを制御する方法や、デバイスをGroup化して制御する機構を提供する

f:id:shu223:20140623071158p:image:w500


デバイス接続手段

  • Bluetooth Low Energy
  • IP

HomeKit Accessory Profiles

f:id:shu223:20140623070906p:image:w500

  • → Service, Characteristicって、BLEのGATTベースプロファイル?
  • NO!

HomeKit Accessory Protocol Layers

f:id:shu223:20140623070646p:image:w500


BLE の GATT、IP の JSON をラップする独自プロトコル


プロトコルやプロファイルの仕様は?

f:id:shu223:20140623070725p:image:w500


要MFi


では、試せないのか?

Home Kit Accessory Simulator

起動方法

[Xcode] > [Open Developer Tool] > [Home Kit Accessory Simulator]


新規アクセサリ作成

[+] > [New Accessory]


f:id:shu223:20140623072048p:image:w600


  • サービス追加
    • Add Light Bulb
    • Add Garage Door Opener
    • Add Thermostat
    • Add Lock
    • Add Switch
  • 有効化
    • スイッチをONに

f:id:shu223:20140623071114p:image:w600


同じ WiFi 内ならこれでアクセサリとして HMAccessoryBrowser から発見できる。


実装方法

(実はこれはプレゼンでは説明してないのですが、簡単に。)

マネージャ生成
self.homeManager = [[HMHomeManager alloc] init];
self.homeManager.delegate = self;
家を生成
[self.homeManager addHomeWithName:@"First Home"
                completionHandler:^(HMHome *home, NSError *error) {
                    
                    if (error) {
                        NSLog(@"error:%@", error);
                        return;
                    }
                }];
部屋を生成して家にaddする
[home addRoomWithName:@"First Room"
    completionHandler:^(HMRoom *room, NSError *error) {
        
        if (error) {
            NSLog(@"error:%@", error);
        }
        else {
            NSLog(@"success!");
        }
    }
];
アクセサリ(周辺デバイス)を探す
self.accessoryBrowser = [[HMAccessoryBrowser alloc] init];
self.accessoryBrowser.delegate = self;

[self.accessoryBrowser startSearchingForNewAccessories];

デリゲートメソッドまわりは省略。


Siri連携

(口頭で話しただけ)


参考資料

動画
  • Designing Accessories for iOS and OS X (701)
  • Introducing HomeKit (213)
Dev Center
  • Home Kit の各クラスリファレンス
  • サンプルはまだない

See Also


ご清聴ありがとうございました!


[iOS][画像処理]【iOS8】CIKernel を使ったカスタムフィルタのつくりかた

$
0
0

Core Image の CIFilter でいろいろなフィルタ処理(画像処理/画像加工)ができるのはみなさまよくご存知かと思いますが、iOS 8 では CIKernel というクラスが追加され、そのフィルタ(CIFilter)を自作できるようになりました。


本記事は、その作成手順について、6/20日に開催された WWDC 2014 振り返り勉強会で発表したものです。もともとアップしないつもりで Markdown でスライドをつくった のをそのまま貼り付けてるので、少々読みづらい部分があるかもしれません。


同勉強会では、この CIKernel の内容がちょっとしかなかったので、同じく iOS 8 の新機能である HealthKit、HomeKit を対応デバイスなしですぐに試す方法 についても話しました。


また(ちょっと古いですが、)Core Image、画像処理関連の記事は他にもいろいろと書いているので、よろしければご参照ください。


CIKernel とは

  • フィルタを自作できる
  • OS X では以前からあった

CIKernelのつくりかた

カーネルはOpenGLのシェーディング言語で書く

kernel vec4 swapRedAndGreenAmount ( __sample s, float amount )
                  { return mix(s.rgba, s.grba, amount); }

文字列として CIKernel の初期化メソッドに渡す

CIKernel *kernel = [CIKernel kernelWithString:kernelStr];

CIKernel を適用する

こんな感じ

- (CIImage *)outputImage
{
    return [[self myKernel] applyWithExtent:self.inputImage.extent
                                  arguments:@[self.inputImage, self.inputAmount]];
}

CIFilter サブクラスをつくる

自作 CIKernel をつかって、CIFilter サブクラスをつくる。

@interface MyFilter : CIFilter

@property (nonatomic, strong) CIImage *inputImage;
@property (nonatomic, copy) NSNumber *inputAmount;

@end

(実装は省略。WWDCスライドにあります)


フィルタとしての使い方は普通の CIFilter と同じ

NSDictionary *params = @{kCIInputImageKey: ciImage,
                         @"inputAmount": @(1.0),
                         };
CIFilter *filter = [CIFilter filterWithName:@"MyFilter"
                        withInputParameters:params];

デモ

(自分で実装したやつがあるのですがスクショは微妙なところなのでWWDCセッションスライドのを貼っておきます。)


f:id:shu223:20140623080037p:image:w600


参考資料

動画
  • Developing Core Image Filter for iOS (515)
Dev Center
  • CIKernel Class Reference (現状 OS X 版のみ

[雑記][制作実績][iOS]「2014年の目標」が全然達成できてない件

$
0
0

ふとしたきっかけ *1 で年初に書いた「2014年の目標」という記事を見返したのですが、おもしろいぐらいに達成できてなくてびっくりしました。


ちょうど2014年も半分経過したところだし、状況もいろいろ変わってこのまま年末まで放置しても仕方ないので、ここでいったん目標を精算(見直し)してみようと思います。


1. 連載を書籍化する → 継続

gihyo.jpでの連載執筆を加速させて、書籍化まで持っていきたい。


という目標で、数値目標を


  • 週1ペースで書いて2月末までにプラス6記事
  • そこから書籍化に向けた加筆作業に入る

と立てていたのですが、2末までにプラス 6記事どころか、7月現在でプラス 1記事。達成率 16% です。


ただ生活の柱にはならないので、他のメイン業務に容易に割り込まれてしまうのが悩みどころ。


まさにこの通りになってます。。


「iOSと連携させて使えるデバイス」は今も興味の中心なのですが、Moff や WHILL など、実際にデバイスをつくっているスタートアップとお仕事させていただけるようになり、既製品に対して用意されている SDK や API でできる範囲で何かやる、というのでは物足りなくなってしまった、というのはあります。



でもまだまだいじってみて紹介したい市販デバイス(ガジェット)はいくつかあるので、何とか数が揃うところまで継続したいところ。。gihyoさん申し訳ありません。。


2. 勉強〜ブログの流れをもう一歩前進させる → 打ち切り、もしくはある意味達成

  • 興味のある技術を勉強する
  • → ブログに書く
  • その技術を使ったミニマルなアプリをつくってリリースする

という流れをつくりたい。

理由の一つとしては、自分でアプリを考えて、リリースするということをもっと継続的にやっておきたいなと。アイデアを考える脳みそは使い続けてないとすぐに腐ってくるし、アプリをリリースしたときに感じられる空気感とかはすぐに古くなるので。


書いてあることはいま読んでも同意できますが、これに対して何もやってません。自分のアプリ、つくってないどころか、考えてもいない。たまに思い浮かんだアイデアを書き留めたりはしてますが、それをつくろうという発想はまったくなかったです。


とはいえ、この記事を書いた当時は「フリーランスとしてやっていこう」とはまだ決めていなかったという大きな状況の違いがあり、


もうひとつの理由は、「興味のある技術を勉強する」をちょっとでも収益化すること。ブログに書いてもあまりお金にならないし、すぐに仕事に使えるものばかりでもないので。


こっちに関しては、フリーランスになった今となっては ブログが営業ツールとして機能しているという点で、ある意味目的達成できてるなーと。


あと TimeTicket もブログマネタイズ手段のひとつになりそう、と思っています。


というわけで個人名義でアプリをつくって出す、というのは大事だとは思うけど、2014年の目標としてはもういいかなと。


3. 個人でKindle書籍出版 → 継続

仕事で使う予定もないし、個人アプリで使う予定もない。でも興味はある、という技術ネタを、単にブログに書いて終わり、ではなくちょっとでもマネタイズしたいというのはずっと思っていて、出版社からちゃんとした本として出すのはプレッシャーやハードルが高いので、そういうものをまとめた寄せ集めTips本をKindleで個人出版してみたいなと。


自分が興味を持ったネタは自分以外にも興味がある人はいるはず。儲かりはしないだろうけど、自分の勉強になるからやって損はない。


まだ全然何もやってないんですが、僕の中では進んでいます。


この目標は継続で。


4. 「旅するプログラマ」構想 → 独立したので打ち切り

アメリカで2年ぐらいは働くぞと思って鎌倉のアパートも解約して家具も処分したのですが、わずか数ヶ月で帰国することになったので、幸か不幸か住所がよくわからないことになってます。


こういう状況(ちゃんとした家と家具がない)ってなかなか意図してつくれるものじゃないので、「いろんなところを転々としつつ仕事をする」といういつかやりたいと思っていたことを実行に移す絶好のチャンスなんじゃないかと。


ほんとに沖縄のウィークリーマンションを1ヵ月間予約するところまではやったんですが、その後しばらくして「自分はまだ沖縄とかいってる場合じゃない」と再考させられる出来事がありまして。


実際、プログラマなので遠隔で仕事をやること、そういう仕事を獲得することは可能だとは今でも思うのですが、(自分にとって)付加価値のある、次のステップにつながるような仕事となると、遠隔だと難しいなと。


そんなわけでフリーとしてしっかりやっていこう、と決心し、都内のアパートを契約し、「旅するプログラマ」構想は当面の凍結となったのでした。


書籍執筆、とかの「ひとりでまとまった期間籠ってやる仕事」とかをやることになればまたどっか行ってやるかもしれません。


5. Androidアプリをつくる → 継続

専門はあくまでiOSに置きつつ、趣味のアプリ/実験アプリをつくれる程度に *1 なっておきたい。


理由としては、審査なしでアプリをさくっと出せるという点が、ブログの一歩先のアウトプット先として向いているなぁというのと、Google Glassみたいに楽しそうなデバイスが出たときに、iOS SDKは最初はないとかAndroidのほうが簡単にいろいろ制御できるというケースがこれからちょくちょく出てきそうなので。


これも何もやってない。。まず端末の1台ぐらい買おう。。


端末買って、丸1日ぐらい集中すれば、習作的なものをGoogle Playに出すところまではいけるかなと楽観的に考えているので、この目標も継続。


6. 一緒に仕事したい人と仕事をする → わりと達成できている!?

一緒に仕事したい人に自分から会いに行って売り込む、ということを昨年末あたりから始めていて、これをもっと形にしていきたい。


会ってもらうことはできて、いいですね、ぜひ一緒にやりましょう!からなかなか具体的にできていないのが現状。


もっと頭を絞り、自分にしか出せない価値や自分だから背負えるリスクといった武器を持って、相手が僕と「今」組む理由を明確に打ち出して動く必要がある。


これは唯一順調に進んでいる気がします。


今月末に5〜7月の実績まとめ記事を書く予定ですが、この3ヵ月も楽しいお仕事ばかりさせていただいてます。感謝。


おわりに

そんなわけでその後フリーランスとして独立することになり、目の前の仕事を達成するのに精一杯で年初に立てた目標なんて忘れていたわけですが、仕事そのものが次のステップに繋がっているものばかりなので、結果的にはまぁいいかなと思っています。あと半年、引き続きがんばります!


*1:半年かけて3ブックマークに達して、本ブログのサイドバーに置いてる「新着エントリー」に入ってきた

[雑記][iOS]TimeTicket で日曜の空き時間が 41,000 円で売れた話

$
0
0

「わたしの30分、売りはじめます。」という触れ込みでオープンした空き時間売買サービス「TimeTicket」、さっそく登録してみたところ、ちょうど空いてた昨日の日曜だけでなんと 41,000円 の売り上げがありました。


f:id:shu223:20140707074629j:image:w600


このサービス、気になってる方も多いんじゃないかと思うので、実際どんな感じだったか書いておこうと思います。


※本記事は申し込み主の方に許可をとった上で書いています。堤のチケットに申し込むとブログに書かれてしまう!ということはないのでご安心ください。


売れたチケットその1:iOSアプリ開発に関する諸々の相談に乗ります。

https://www.timeticket.jp/items/1890

  • 30分500円〜、寄付率50%
  • 場所は目黒にあるコワーキングスペース、HUB Tokyo限定

最初に登録したチケット。受け取れる額は TimeTicket の手数料が30%引かれてそこから寄付が 50% なので、支払額が500円だとすると、


500円 × 0.7 * 0.5 = 175円


というわけで(チケット発行側としては)儲けは度外視。どんなもんか使ってみよう、の値段です。なるべく出かけたくないので、場所は自分が歩いていける&入居しているコワーキングスペースにしています。


売れたチケットその2:iOSアプリを開発します。

https://www.timeticket.jp/items/1903

  • 5時間40,000円、寄付率10%
  • 場所指定は東京都

こっちはフリーランスでやってる本業。まだ TimeTicket でこの金額を支払う人はいないかなーと思ってたら申し込みがきてびっくりしました。仕事としての意識があるので、場所は先方におまかせ。


事前のやりとり

申し込みがあって、チケット発行側(今回のケースでは僕)がOKボタンを押すと、申込者が決済できるようになる、というフローなのですが、どっちのチケットでも、OKボタンを押す前にダイレクトメッセージで

  • 具体的な相談内容/開発内容
  • 期待しているゴール

は確認しました。あまり知らない分野かもしれないし、先方のゴールイメージ次第では30分以内/5時間以内で期待されている成果を出せるとは限らないし、お金の無駄だった、となると先方はもちろん自分もとても哀しいので。


聞いてみて、それならお役に立てそうだ、ということで OK ボタンをポチッと。


当日

相談30分チケットの方は、技術的な質問2つほどと、勉強方法とかざっくばらんな話 *1


(ブログに書いていただきました!)



また、開発5時間チケットの方は、iOSエンジニアの方からの申し込みだったので、開発委託という感じではなく、行き詰まっている部分のソースコードと issue のリストをその場でもらって、僕の手元で issue やバグに対応しつつ解説する、というやり方でした。(受け取ったソースコードは最後に横で確認してもらいつつ消去)


所感

フリーランサーとしての感想

「その2」の方のチケットは自分の本業と同内容なわけですが、自分に入る金額は、


40,000円 × 0.7 × 0.9 = 25,200円


で、寄付額が最低でも10%なので、お客さんが支払う額の 63% が受け取れる率の最大、ということになります。


なのでここをご飯を食べるための主戦場にする(フリーランスとしての活動の場にする)には厳しいですが、「空き時間を売る」という観点では全然アリ、というのが自分の感想です。


格安チケットのメリット

申し込みがあってから気付いたのですが、時間帯を午前中の10時〜10時半にすると、午前中うだうだしがちな自分にとっては「出かけるきっかけ」になって良いなと。仕事に関係する話だからエンジンもかかってくるし、技術的な相談は自分の勉強にもなるし。


要望とか

あったらいいなーと思った機能は、

  • チケットの埋め込みコード生成
    • この記事に埋め込みたかった
  • タイムセール
    • 突発的に暇になって、でも急だから申し込みないだろうな、というときに格安にしたい
    • このために別途チケット発行するのはあまりやりたくない。いいね数とかあるので。
  • チケット一時休止
    • 忙しいときは休止にしたい
  • お気に入り
    • 上記のセール機能や休止機能と関連して、お気に入り登録してくれた人に通知が行くような機能

中の方々、いかがでしょうか!


*1:勉強方法は、せっかく質問していただいたのに的を得た回答をできなかった気がするので、あとで整理しておこう。。

[iOS][Objective-C]【iOS8】App Extension の実装方法 その2:Custom Keyboard

$
0
0

その1:Action」から1ヵ月以上経ってしまいましたが、「その2」として Custom Keyboard の App Extension 実装手順について書きたいと思います。 *1



キーボードは改善し続けてきた iOS の中でもわりと進化が止まっていた/むしろ使いづらくなるアップデートもあった部分なので、自前でのキーボード実装を可能とする機能追加は期待していた人も多かったのではないでしょうか。


1. ターゲットを作成する

Xcode の [File] > [New] > [Target] から、[Application Extension] > [Custom Keyboard] を選択します。


f:id:shu223:20140606093345j:image

(※NDAに配慮し、Xcode6のスクショではなく、公開情報である App Extension Programming Guide の図3-1 を貼ってあります。)


2 Extension の実装

自動生成されたコードについて

手順1でターゲットを追加すると、UIInputViewController のサブクラス "KeyboardViewController" が自動生成されます。


UIInputViewController のヘッダを見てみると、

@protocol UITextDocumentProxy <UIKeyInput>

@property (nonatomic, readonly) NSString *documentContextBeforeInput;
@property (nonatomic, readonly) NSString *documentContextAfterInput;

@end

NS_CLASS_AVAILABLE_IOS(8_0) @interface UIInputViewController : UIViewController <UITextInputDelegate>

@property (nonatomic, retain) UIInputView *inputView;

@property (nonatomic, readonly) NSObject <UITextDocumentProxy> *textDocumentProxy;

- (void)dismissKeyboard;
- (void)advanceToNextInputMode;

// This will not provide a complete repository of a language's vocabulary.
// It is solely intended to supplement existing lexicons.
- (void)requestSupplementaryLexiconWithCompletion:(void (^)(UILexicon *))completionHandler;

@end

こんな感じでカスタムキーボード用に拡張された UIViewController サブクラスとなっています。


参考:UIInputViewController Class Reference


で、生成されたコード(KeyboardViewController)の中身を見てみると、viewDidLoad で下記のような処理が行われています。

self.nextKeyboardButton = [UIButton buttonWithType:UIButtonTypeSystem];

[self.nextKeyboardButton setTitle:NSLocalizedString(@"Next Keyboard", @"Title for 'Next Keyboard' button") forState:UIControlStateNormal];
[self.nextKeyboardButton sizeToFit];
self.nextKeyboardButton.translatesAutoresizingMaskIntoConstraints = NO;

[self.nextKeyboardButton addTarget:self action:@selector(advanceToNextInputMode) forControlEvents:UIControlEventTouchUpInside];

[self.view addSubview:self.nextKeyboardButton];

NSLayoutConstraint *nextKeyboardButtonLeftSideConstraint = [NSLayoutConstraint constraintWithItem:self.nextKeyboardButton attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0.0];
NSLayoutConstraint *nextKeyboardButtonBottomConstraint = [NSLayoutConstraint constraintWithItem:self.nextKeyboardButton attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0];
[self.view addConstraints:@[nextKeyboardButtonLeftSideConstraint, nextKeyboardButtonBottomConstraint]];

パッと見長いですが、やってることは

  • UIButton オブジェクト生成
  • Auto Layout の制約追加

ざっくりこれだけです。


ポイントとしては、生成した UIButton にアクションとしてセットされている advanceToNextInputMode メソッドです。UIInputViewController のリファレンスに

Switches to the next keyboard in the list of user-enabled keyboards.

とある通り、キーボード切り替えのためのメソッドです。


つまり、この自動生成されたキーはキーボード切り替え用のキー、ということがわかります。


文字入力キーを追加する

独自の文字入力用のキーを追加してみます。

UIButton *customKeyBtn = [UIButton buttonWithType:UIButtonTypeSystem];
[customKeyBtn setTitle:@"@shu223" forState:UIControlStateNormal];
[customKeyBtn sizeToFit];
[customKeyBtn addTarget:self
                 action:@selector(customKeyBtnTapped:)
       forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:customKeyBtn];

上記のように普通に UIButton オブジェクトを生成して、アクション用のメソッドを次のように実装します。

- (void)customKeyBtnTapped:(UIButton *)sender {
    
    [self.textDocumentProxy insertText:@"https://twitter.com/shu223"];
}

これで、キーの押下時(タップして離したとき)に、 UITextView なり UITextField なりの UIKeyInput プロトコルを実装したビューで、かつ First Responder なものに対して指定の文字列が挿入されるようになります。


カスタムキーボードを使用する

作成した App Extension のターゲットを内包するアプリ(Containing App)を実機 / シミュレータにインストールするとそのカスタムキーボードが使えるようになるわけですが、有効にするためにはエンドユーザー側で設定のひと手間が必要です。


NDAに配慮してスクショは控えますが、iOS の「設定」アプリから次の手順でカスタムキーボードを有効にします。

  1. [Settings] > [General] > [Keyboard] > [Keyboards]
  2. [Add New Keyboard] を選択
  3. リストの中に作成したカスタムキーボードがあるはずなので、タップして有効にする

これで、メールアプリなりメモ帳アプリなりを起動して、テキスト入力中にキーボード切り替えするとカスタムキーボードが出るようになります。


参考資料


*1:一応 Extension Point は 6種類全部試してみるつもりでいるので、ゆっくりながらも「その6」まで続く予定。

[iOS][音声処理]低レイテンシにシーク&再生可能なライブラリ:EZAudio

$
0
0

ニッチなケースだとは思うのですが、

  • デバイスA(マスター)に対して、デバイスBを同期再生させたい
  • ダンスパフォーマンスなので遅延はNG
  • デバイスBのアプリは、デバイスAの再生の途中で起動されるかもしれない
    • つまり、同期タイミングが曲の頭だけでは不十分
    • ライブパフォーマンスなので一発勝負
  • デバイスBは100台ぐらい

という要件の案件があり、曲中にもちょこちょこと同期タイミング(※)を用意して、デバイスBではその度に再生位置を変える(シークする)という方法を取ろうとしました。


※同期方法には Audio Watermark (音響透かし)を使用。この話はまた後日書きます。


で、やってみると、デバイスAとデバイスBの再生音がたまにずれる。常にずれているなら同期方法自体の問題と考えられますが、「たまに」ずれるというのは、AVAudioPlayer の currentTime プロパティを使用したシーク時に遅延が生じているのかなと。(もちろん prepareToPlay とかはやっています)


ググってみると、「AVAudioPlayer も昔はレイテンシがひどかったけど、今はだいぶ改善された」みたいなコメントもあり、「AVAudioPlayerは遅い」という確証はイマイチ持てず。


でもまぁ高レベルAPIなわけだし、もうちょっと低レベルなAPIを使っていて低レイテンシを売りにしているライブラリとか当たってみよう、といろいろ調べてみると、OpenALをラップしてるいくつかのライブラリは、「低レイテンシ」をうたってはいるものの、長めの楽曲については結局 AVAudioPlayer を内部で使ってたり。。(例:ObjectAL)


EZAudio

で、たどり着いたのが、EZAudio という OSS。


https://github.com/syedhali/EZAudio



良さそうと思った点は、

  • 内部では Audio Unit を使用
  • 最近もわりと活発にメンテされている
    • オーディオ系 OSS は古いことが多いので。。
  • スター数が多い
    • すなわちユーザー数が多くてある程度枯れてそう(希望的観測)
  • API は AVAudioPlayer 並に簡単、とまではいかないが Audio Unit を直接使うよりは簡単
  • 波形描画機能もライブラリに含まれていて、OpenGLを用いた高速描画もサポート
    • CoreGraphicsベースも選択可能

実装方法

EZOutputDataSource プロトコルへの準拠を宣言しておく。


再生準備

ファイル読み込み等。

@property (nonatomic, strong) EZAudioFile *audioFile;
self.audioFile                        = [EZAudioFile audioFileWithURL:filePathURL];
self.audioFile.audioFileDelegate      = self;

[[EZOutput sharedOutput] setAudioStreamBasicDescription:self.audioFile.clientFormat];

EZOutputDataSource実装
- (void)               output:(EZOutput *)output
    shouldFillAudioBufferList:(AudioBufferList *)audioBufferList
           withNumberOfFrames:(UInt32)frames
{
    if (self.audioFile) {
        
        UInt32 bufferSize;
        [self.audioFile readFrames:frames
                   audioBufferList:audioBufferList
                        bufferSize:&bufferSize
                               eof:&_eof];
    }
}

- (AudioStreamBasicDescription)outputHasAudioStreamBasicDescription:(EZOutput *)output {
    return self.audioFile.clientFormat;
}

再生開始
if (![[EZOutput sharedOutput] isPlaying]) {
    [EZOutput sharedOutput].outputDataSource = self;
    [[EZOutput sharedOutput] startPlayback];
}

再生停止
if ([[EZOutput sharedOutput] isPlaying]) {
    [EZOutput sharedOutput].outputDataSource = nil;
    [[EZOutput sharedOutput] stopPlayback];
}

シーク

NSTimeIntervalでシーク位置を指定したい場合はこんな感じ。

SInt64 frame = self.audioFile.totalFrames * newTime / self.audioFile.totalDuration;
[self.audioFile seekToFrame:frame];

UISlider の位置でシークさせたい場合は付属のサンプルまんまでOK。


使ってみた所感

実際これに入れ替えてみると、「同期再生のずれ」は大幅に軽減されました。ちゃんと計測してないのですが。


関連記事



[iOS][デバイス連携][ガジェット]自作iOSアプリで制御できるロボット、Romo のハッカソンに参加してきました

$
0
0

本日 HUB Tokyo にて開催された『iPhone x ロボットハッカソン 大人の夏休みの自由研究 〜Romoで絶対起きられる目覚まし時計を作ろう〜』と題されたハッカソンに参加してきました。



Romo とは?

http://www.romotive.jp/

Romo(ロモ)はiPhoneなどで動く「体感型のエデュケーショナルロボット」で、誰でも動かすことが可能です。iPhoneアプリが頭脳の役割になり、様々な感情や動きを表現することができます。楽しみながら子どもの論理的思考や想像力、思考力を育むことができ、遊びや学びの幅がさらにひろがる可能性を秘めています。


僕なりに要約すると、「iOS SDK が用意されてて、いろんな連携アプリがつくれるロボット」です。


Romo SDK の使い方

gihyo.jp の連載が細かい手順まで説明されていてわかりやすいです。


「とりあえず動かしてみたい」場合は第2回を、


「キャラのUIを使いたい」場合は第3回を見ればOKです。


第2回の内容はRomo本体が必要ですが、第3回の内容は本体なしで試すことができます。


つくったもの

お題は「目覚まし時計」で、セットした時間になると Romo が激しく引っ張って起こしてくれる というものをつくりました。


Romo Alarm from Shuichi Tsutsumi on Vimeo.


撮影のため柱にくくりつけてありますが、これを服や布団に繋いでおくイメージです。だいぶシンプルですが、せっかくロボットなので、物理的に動く機能を使った方が良いかなということでこれに至りました。


止めるには iPhone を抜くしかありません。動画からも僕の動揺っぷりが伝わるかもしれませんが、激しく動くのでかなり大変です。


イヤホンジャックが前にビヨーンと出てるのは、繋ぐヒモが手元にイヤホンしかなかったからで、用途としてはただのヒモです。テープで貼り付けてあります。


f:id:shu223:20140713160602j:image:w300



動画にはありませんが、マイルドに引っ張って起こしてくれるモードもあります。


モーター電流値を取得する

「引っ張る」ということを実現するのに、単純に一定時間ごとに前進と後退を繰り返すのだと「引っ張られてる感」がどうしても弱くなってしまう場合があるので、しっかり張力がMaxに達してから後退するよう、モーター電流の値を判定に使用しています。


モーターを示すクラス RMCoreMotor のオブジェクトは DifferentialDriveProtocol よりアクセスできるので、次のようにします。

@property (nonatomic, strong) RMCoreRobot<HeadTiltProtocol, DriveProtocol, LEDProtocol, DifferentialDriveProtocol> *myRobot;

で、drive するときに `driveWithLeftMotorPower:rightMotorPower:` を使用して走らせることで、


[self.myRobot driveWithLeftMotorPower:1.
                      rightMotorPower:1.];

RMCoreRobot オブジェクトの `leftDriveMotor`, `rightDriveMotor` プロパティから、`motorCurrent` の値を取得できるようになります。

float leftCurrent  = [self.myRobot.leftDriveMotor motorCurrent];
float rightCurrent = [self.myRobot.rightDriveMotor motorCurrent];

Romo が引っ張る際にヒモがピンと張って前に進めなくなると、速度を維持しようとモーター電流が大幅に上がることを利用して、 motorCurrent が一定以上になるといったんバックする、ということをやっています。


苦労した点としては、どんな床で使うかによって閾値が全然変わってくる点で、板の上、アスファルトの上だと全然値が違ってました *1


つくったもの その2

上記のをつくりおえて、このブログも書いてしまって時間が余ったので、もうひとつ作成。


アラームの音楽に合わせて Romo が踊る というもの。


動画は撮ってませんが、アラーム開始に合わせ MIDI の楽曲が鳴りはじめ、そのメロディやリズムに合わせて Romo が体を揺らしたり表情を変えたり雄叫びを上げたり、というものです。MIDI再生とかは別件でやってたのと、アラームはひとつめのアプリのを流用したので制作時間30分ぐらい。


総括

Romo SDK ともてよくできていて、シンプルな API のわりにかなり色々なことができるようによく考えられていると思います。興味のある方はぜひ!


日本での正規品は現在予約受付中(2014年7月24日頃の出荷予定とのこと):


(Amazon で現在手に入るのは並行輸入品で、かつ価格が倍以上します。。)



*1:結局、プレゼンのときに調整できるようにキャリブレーションモードを用意しました。

[制作実績][雑記][iOS]2014年5月〜7月にやったお仕事のまとめ

$
0
0

4月末に書いた「独立して最初の3ヵ月間にやったお仕事のまとめ」という記事から3ヵ月が経ちました。(前にも似たようなこと書きましたが)フリーランスは定期的に自らアピールしていかないと本当に世の中から忘れられてしまうので、またこの3ヵ月やったお仕事についてまとめておこうと思います。


ウェアラブルおもちゃ「Moff」

Moffって何?という方はぜひこちらのムービーをご覧ください。



ざっくりいうと「手に巻いてスマホと連携させて遊べるおもちゃ」です。


Kickstarter で2日間で目標調達額を達成したり、最近予約販売を開始した Amazon では発売前にも関わらず妖怪ウォッチに次ぐ2位にランクインしたりと、とても勢いのあるスタートアップです。


GW明けあたりから、このMoffの、iOSアプリの開発をお手伝いさせていただいてます(現在進行形)。


Moffは現在Amazonにて予約受付中ですので、お子さんがいらっしゃる方はぜひ!



(僕も甥っ子姪っ子自分用等々4つほど購入する予定です)


パーソナルモビリティ「WHILL」

昨年、500 startups に参加 した際に同期だった「WHILL」とも一緒にお仕事させていただいてます。


f:id:shu223:20140723040034j:image:w400


担当してるのは、WHILL と Bluetooth LE で連携する iOS アプリで、BLEモジュールのファーム側にも踏み込んで開発しています。



WHILL本体のファーム側と歩調を合わせる必要もあるので、月に3人日ぐらいのペースでちょっとずつ進めている感じですが、既にWHILLをアプリからリモートコントロール (ベッドにWHILLを呼び寄せて乗るといったユースケースを想定)できるようにはなっていて、あとは、

  • 速度やバッテリー残量等の情報取得・表示
  • シートの前後スライドのコントロール
    • 乗る際に、乗りやすいようにシートを前にスライドさせる
    • 車椅子ユーザにとってかなり重要らしい
  • 細かい速度関係のパラメータチューニング
    • 前進加速度、前進減速度、後進加速度、後進減速度、等々パラメータは20種類ぐらいある
    • デフォルト設定が3タイプ用意されているが、人によって好みが全然違う
    • アメリカは広いので、サービスマンがやってたらコストが半端なくかかる

といったあたりを実装する予定です。8月が山場になる見込み。


真鍋大度さん「music for the deaf」

『情熱大陸』でラストにやってた、「耳の聴こえないダンサーが、電気刺激で音を感じてダンスする」という試み。これ、筆談してるあたりでちょうど葉加瀬太郎さんによるあの名エンディングテーマが流れ始めて、うおーってなった方も多いのではないでしょうか(僕は超なりました)


これを「ヨコハマ・パラトリエンナーレ」というイベントで実際に展示&パフォーマンスするにあたって、電気刺激デバイス(通称ピリピリデバイス)をBLEから制御するアプリ、その他諸々の制作のお手伝いでお声がけいただき、二つ返事でお受けした次第です。


(アプリ動作確認の様子。感電初心者なので毎回ドキドキします。。)


f:id:shu223:20140723042423j:image:w400

(サイトに名前載ってたので記念スクショ)


パフォーマンスの日時等の詳細については、近いうちに公式サイトで告知されると思います。また技術的な話については終了後にでも本ブログに書きたいと思っています。


海外iBeacon案件

iBeaconはリアルな場所に関わるので、仕事で海外出張いけるかも!?という期待もあり関わらせていただいた(ている)案件。


この案件は日本の会社からお話をいただいたものなのですが、クライアントは海外、ディレクターも外国人、ということで基本的にコミュニケーションはすべて英語というところが僕にとってはチャレンジングでした。不自由だしうまく言えないもどかしさはあるものの、自分の得意領域(アプリ開発)では意外となんとかなる、という感覚を得られたのがよかったです。


スケジュールの都合で、最初の仕様検討とプロトタイプ開発フェーズでいったんプロジェクトを離れましたが、引き続きスポットでお手伝いさせていただく予定。


講演

『第37回ワイヤレス技術セミナー 実例から探るiBeaconの勘所』という有料セミナーで講演をさせていただきました。

iBeaconが発表されてからすでに1年が経とうとしていますが、この新技術をレストランなどの「リアルビジネス」に実際に活用し運用している事例はまだ国内ではほとんど出てきていません。株式会社ウェブクルーは、このiBeaconにいち早く着目し、自社で展開している火鍋専門店チェーン「小肥羊」の実店舗にビーコンデバイスを設置し、対応するiOSアプリを2014年3月にリリースして話題となりました。


本講演では、この実店舗アプリ/サービスの開発に携わった立場から、どのような体制・スケジュールで開発を実施したのか、プロトタイプでの実証実験はどのようなものだったのか、その実験で得た知見を踏まえアプリ/サービスをどのように設計していったか、といった点を中心に詳しく解説していきます。また、リリース後の反響や成果、店舗スタッフの反応などについても最新の状況を報告します。


ウェブクルーさんのご厚意で、非公開情報をふんだんに交えて(ビーコンどこに置いてるとか、管理画面がどうなってるかとか)お話させていただきました。


動画撮影・編集アプリのプロトタイプ開発

発注元の会社のオフィスに1日だけ行って、動画撮影・編集アプリのプロトタイプを開発するお仕事。先方がこれからアプリ開発をはじめるにあたり、そのたたき台となるような位置づけです。 *1


「想像力で補完できる部分はできるだけ端折って、まずはそのアプリの良さがわかる一番重要なポイントだけしっかり実装する」みたいなプロトタイピングの勘所のようなものは、かなりたくさんのアプリをつくってきた中で培われてきている(と思っている)ので、こういう短期ブッコミ案件大歓迎です。


その他

タイムチケット経由のお仕事

最近オープンした『TimeTicket』経由でもちょくちょくお仕事の依頼をいただいてます。


「相談」の方ではなく、本業の「アプリ開発」のチケットで、今日までに実行できたのは2件。


昔つくったアプリのリバイバルヒット

4年ほど前につくった「i聖徳太子」というアプリが謎のリバイバルヒットし、

  • ビジネスカテゴリ1位
  • 無料総合46位

に躍り出てきました。


下記のダウンロード数の推移グラフを見ると、そのスパイクっぷりがよくわかります。


f:id:shu223:20140723035746p:image:w600


火がつく前日が14ダウンロード、ピークが16,426ダウンロードなので実に1000倍


発火元は下記ツイートのようです。なんとリツイート 18,704 件、お気に入り 8,590 件!!



ちゃんと計算してませんが、Macbook Airが買えるぐらいの収益増になってました。


WWDC 2014 参加

仕事というよりは旅行ですが、17日間、つまりこの3ヵ月の約6分の1にあたる期間は、初のWWDCに参加するべくシリコンバレーに行ってました。

WWDC以外にも、WHILL HQ に行ったり、Kinoma Create を開発している Kinoma に行ったり、いろんなスタートアップの方に会ったり、向こうにいるデザイナーともくもく開発したりと非常に充実してました。


(あこがれのあのジャケットをもらいその場で記念撮影)


超楽しかったので来年も行きます!


おわりに

そんなこんなで、おかげさまでこの3ヵ月も楽しく生き延びることができました。フリーランスとしてどう仕事をしていくか、エンジニアとしての自分の強みは何で、どう生存していくか、みたいなものが紆余曲折の中で揉まれてだいぶいい感じになってきた気がします。


で、前回の実績紹介のときに書いた、

  • 目の前のおもしろい仕事にがっちり食いつく
  • → がんばっていい仕事をする
  • → 得られたスキルや実績をブログ等でアピールする
  • → よりおもしろい仕事のお話をいただく

というサイクルをしっかり回していく「わらしべ長者方式」がやっぱり自分にあったやり方であり、生命線だなと。

要は「おもしろく働くために自分が心がけていること」的な内容で、8月26日、下記イベントでお話しさせていただきます。



この話は以前ブログに書いてみたことがあるのですが、イマイチ伝わらなかった気がするので今度こそはしっかり例とか準備して臨むつもりですので、ピンと来た方はぜひご参加いただけると嬉しいです。


*1:この案件は7/23現在ではまだやってないのですが、7末に予定を入れてるので、今回の実績に入れてあります。

[制作実績][iOS][Bluetooth][デバイス連携]音楽に合わせて電気を流すiOSアプリ

$
0
0

先日『2014年5月〜7月にやったお仕事のまとめ - Over&Out その後』でちらっと書いたのですが、最近のお仕事のひとつとして、音楽に合わせて電気を流すアプリを開発しています。


(開発中の風景 in 新幹線)


4ch の電極を持つ電気刺激デバイス(通称ピリピリデバイス)に、音楽に合わせて BLE 経由で制御コマンドを送る もので、耳の聴こえないダンサーが、音楽を「感じ」ながらダンスをするためのデバイス&アプリです。


デモンストレーション on 8/13

このアプリはもともと 真鍋大度さん からご依頼いただいて開発しはじめたもので、「ヨコハマ・パラトリエンナーレ」というイベントで、8月13日、真鍋大度 + 石橋素 + 照岡正樹 + 堤修一 × SOUL FAMILY 名義で、実際にこのデバイス&アプリを使ったデモンストレーション(ライブパフォーマンス+トーク)を行います。


ヨコハマ・パラトリエンナーレ2014では、聴覚障害のダンサー SOUL FAMILYとライゾマティクス真鍋大度・石橋素、デバイスエンジニア照岡正樹、iOSアプリ開発 堤修一の共同作業により制作された、電気刺激デバイス作品「music for the deaf」の体験用デモ機を展示します。


本プレゼンテーションでは、聴覚障害のダンサー SOUL FAMILYが実際に電気刺激デバイスを使用したショートデモンストレーションを発表する他、真鍋大度、照岡正樹、SOUL FAMILY他によるトークショーを行います。


で、このデモンストレーションは、要事前申し込みで、申し込みフォームが結構見つけづらいところにある *1 ので、ここに直接リンクを貼っておきます。


http://www.paratriennale.net/post-118/


申し込み締め切りは 8/6(明日!) です。


システム構成とか

ちなみにデモンストレーションのシステム構成はこんな感じになってます。


f:id:shu223:20140805084608p:image:w600


ピリピリデバイスを BLE で制御するのはダンサー用 app で、母艦の MBP から OSC でコントロールできるようになっています。(母艦からコントロールするのは再生開始/停止、曲の選択等々で、ピリピリデバイスの制御自体はiOSアプリがスタンドアロンで行う)


また、ダンサーの感じている電気刺激をピリピリデバイスなしで体感できるよう、バイブで疑似体験できるアプリも準備中です。こちらは、台数やら会場インフラやら距離やらを考慮して、音響電子透かし という、非可聴域の音波を利用して、音に情報を埋め込む技術 *2 を用いて、再生タイミングの同期を行います。


FAQ

Q: なぜスマホアプリなのか?

もともとPCからステレオケーブルで繋いで使う有線ピリピリデバイスは真鍋さん&石橋さん&照岡さんで以前開発したものがあって、ポータブル化する(ダンサーが身につけられるようにする)というのが今回の新規開発のテーマでした。


無線で電気刺激コマンドを送る、のであればPCからでもいいのですが、ダンサーがダンスするためにPCも必要になるよりはスマホひとつでできた方が「ポータブル」だし、WiFiがない場所でも使用可能という点でBLE、ということなのかなと。 *3


Q: 今までどうやって踊っていたのか?

このデバイスが出来る前から SOUL FAMILY はダンスをしていたわけで、メンバーの佐山さんに聴いてみたところ、

  • 音楽が会場に大音量で流れることによる振動を感じて踊る
  • 多少聴こえるメンバーの動きを見て踊る

みたいな感じだそうです。すごい。


Facebook での佐山さんの告知ポスト

ついに夢が叶います。音楽が上手く聞く事が出来ず、

フラットに音楽を感じる事が出来ず悩んでいた。

真鍋さんと出会い、いろんな方の協力でついに

夢のデバイスが出来ました。ぜひ皆さん見に来てください!

まだまだ「音楽を感じる」には改善の余地があるのでがんばります。


Q: なぜ電気なのか?

これ僕も当初よくわかってなくて、他の刺激でもいいけど真鍋さんといえば電気、みたいな感じで電気なのかなぐらいに思ってたのですが、ピリピリデバイスをつくった照岡さんが言ってたのは、刺激が処理される速度(?)が、電気が一番早いんだそうです。他の、たとえば叩くような刺激だと、それがいったん脳で処理されて、それが云々かんぬん、で遅いと。


Q: 展示バージョンとの違い

ヨコハマ・パラトリエンナーレの会期が1ヵ月以上と長期にわたるため、メンテナンス性を考慮して、ピリピリデバイス自体は有線版を展示しています。


f:id:shu223:20140805090542j:image:w400


流れているダンスの動画は、実際に耳の聴こえないダンサーがアプリ+BLE版ピリピリデバイスで踊っているもの。


あと、電気を体感してもらうのは説明員が常についてないと厳しいかなという判断で、ソレノイド振動子を用意しています。



*1:NEWS > 「music for the deaf」プレゼンテーション > 申込フォーム

*2:日本エヴィクサーさんに技術提供いただいてます。終了後、別途記事を書く予定。

*3:僕に依頼がきた時点でスマホアプリ(iOSアプリ)であることは確定していたわけなので、あくまで僕なりの推測。

[iOS][制作実績][デバイス連携][Bluetooth]真鍋大度さんとの初仕事 ”music for the deaf” 振り返り

$
0
0

昨日「ヨコハマ・パラトリエンナーレ2014」の特別イベントとして、 SOUL FAMILY × 真鍋大度 + 石橋素 + 照岡正樹 + 堤修一 名義で、『music for the deaf プレゼンテーション』を行いました。


先日書いた記事『音楽に合わせて電気を流すiOSアプリ - Over&Out その後』で紹介した、「耳の聴こえないダンサーが、音楽を「感じ」ながらダンスをするためのデバイス&アプリ」を使って、聴覚障害のダンサーチームが実際にその場で電気刺激だけでダンスをする、というものです。


f:id:shu223:20140814072519j:image:w400

電気刺激デバイス(通称ピリピリデバイス)


申し込み制のイベントだったのですが、定員に対して倍以上の応募があったそうで、大盛況のうちに終わりました。


現在、当日の動画やインタビュー、各種技術説明等を含むアーカイブサイトが制作されているそうで、詳細はそちらに期待しつつ、ここでは個人的な目線から振り返っておきたいと思います。


参加の経緯

電気刺激を用いたさまざまな試みは真鍋さん、石橋さん、照岡さんが従来からやってきたことで、今回の新規開発のテーマは 「ポータブル化」 (ダンサーが身につけられるようにする)でした。


で、iOS & BLE でポータブルにしたいということで、真鍋さんよりメールをいただいたのが、今年の4月。

耳が聞こえないダンサーのために
電気刺激のデバイスを制作したいなと考えております。
PC版は出来ているのですが、iOS BLE版を作成したいです。

もともと iOS × デバイス with BLE は僕がいま一番興味がある技術分野だし、このプロジェクト自体は「情熱大陸」で見て知っていて、すごくインパクトのあった部分だったので、超二つ返事でお受けしました。


で、その後しばらく動きはなく、6月後半になって「ピリピリデバイスBLE版」(詳細後述)が完成し、ライゾマオフィスに行ってそれを受け取ってからアプリの制作を開始した、というのが大まかな参加の経緯です。


(余談:もっと昔の経緯)

真鍋さんは超々有名クリエイターなので、同業な方々から、一緒にお仕事させてもらえるようになった「そもそもの経緯」を聞かれることがあります。


きっかけは非常にシンプルで、「僕がライゾマの求人に応募した」というのが最初です。


昨年末、日本に帰国して今後の身の振り方に迷っていたころにちょうど「スマートフォンエンジニア」という枠で Rhizomatiks が募集をかけていて、真鍋さん/ライゾマに興味があったので、応募。


その後TVで「情熱大陸」を見て、(影響を受けやすい僕は)ものすごくテンションがあがり、翌朝にはまだ何も決まってないのに当時所属していた会社のCEOに退職したい意志をメール、その1ヵ月後ぐらいの面接で初めて石橋さんと真鍋さんにお会いし、10分しかない面接の中で、「採用には至らないとしても、iOS 絡みでは確実にお役に立てると思うので、ぜひぜひぜひお声がけください」とアピールし、その後実際に採用には至らなかったものの(笑)、iOS が絡みそうな際になんとなく思い出してもらえるポジションを得た、というのが経緯です。


僕は iOS しかできないシングルスタックエンジニア(※スタックしてない)ですが、ひとつの技術に張り続け、発信し続けることでこういう役得もあるんだなーと。


ちなみに僕が真鍋さん/ライゾマさんに惹かれるポイントは、アート的なかっこいい側面よりも、まだ論文や研究開発の世界でしか知られていない尖った技術を発掘してきて、それを一般の人にもわかるキャッチーさで応用するというあたりです。今回の music for the deaf 然り、「表情を人工的につくれるか?/コピーできるか?」とかも然り。


つくったアプリ

ダンサー用アプリ、お客さんが疑似体験する用のアプリの2つを制作しました。


どちらもデモ用ということでデザイン面では凝ったことをせず、UIKitの標準コンポーネントをそのまま並べてUIを構成しています。


ダンサー用アプリ

音楽に合わせて電気を流すアプリ。MIDIファイルを解析し、再生に合わせてピリピリデバイス制御コマンドを生成、 BLE 経由で送信します。


f:id:shu223:20140814072602j:image:w240


ダンサーそれぞれのiPhoneにインストールして使用します。


f:id:shu223:20140814072643j:image:w400

(本番で使用したiPhone3台)


iPhoneとデバイスの距離が開いてBLE接続が切れる可能性があるので、今回はポケットに入れて踊ってもらいました。


観客用アプリ

ダンサーの感じている電気刺激を、iPhoneのバイブで擬似的に体感するためのアプリ。ダンサー用アプリと同じMIDIファイルを持っていて、曲に合わせてバイブを作動させます。


f:id:shu223:20140814072715j:image:w240


台数、会場インフラ、距離を考慮して、再生タイミングの同期には「音響透かし」という、非可聴域の音波を利用して、音に情報を埋め込む技術を利用しており、アプリを起動しておけば、自動的に会場BGMに同期して再生が開始されるようになっています。


音響透かしは、日本エヴィクサー社より技術提供いただきました。

iOS用のSDKが用意されていて簡単に導入できるので、こういうライブパフォーマンスでの多人数向け用途には非常にオススメです。


ピリピリデバイス

電気刺激デバイス(ピリピリデバイス)は照岡さんという、真鍋さんと古くから一緒にやっている方が制作されたもので、4chの電極を持ち、シリアル通信でそれらのon/offや電流の強度、周波数などを制御できるようになっています。


f:id:shu223:20140814072741j:image:w400

(ピリピリデバイス完全体)


上の写真の通り、BLE の部分は Konashi を使用していて、シリアル通信(UART)でコマンドを送るようになっています。


ダンサーはこれをケースにしまったうえで、伸縮性があって体に巻けるベルトのポケットに入れて身につけています。(ケースとベルトは石橋さん制作)


ピリピリデバイスのコマンド体系

ピリピリデバイスを制御するためのコマンドは次の4種類。UARTで送る1バイトのうち先頭2ビットがコマンド種別を示しています。

  • 0,0,T7,T6,T5,T4,T3,T2
  • 1,0,I7,I6,I5,I4,I3,I2
  • 0,1,T1,T0,L3,L2,L1,L0
  • 1,1,C1,C0,R3,R2,R1,R0

T7-T0:パルス周期

f=1/((T+1)*128*10^-6*2*2)

かなり細かく設定でき、アプリでも一応可変にしてあったのですが、今回のパフォーマンスでは最大周波数(一番刺激が鋭い)に固定して使用していました。


I7-I2:出力電流値

I(mA)=(((I/255)*(5-0.5))/100)*1000

これは人によって好みが全然違うので、ダンサーごとにそれぞれ設定していました。


C1,C0:出力電圧方向のコントロール
  • C1=1,C0=1 -> 出力全OFF
  • C1=1,C0=0 -> L(+) -> R(-)固定
  • C1=0,C0=1 -> L(-) <- R(+)固定
  • C1=0,C0=0 -> ±モード(通常モード)

今回は通常モード固定で使用。他のモードはこれから別の試みで使用する予定です。


L3-L0,R3-R0:出力電極ch選択

4組の電極と、MIDIの各トラックとの対応は、

  • ch0: キック
  • ch1: スネア
  • ch2: ハイハット
  • ch3: メロディ

となっていのですが、これもダンサーごとそれぞれ設定。すべてONにする人、キック&スネアの大まかなリズムだけを好む人等、それぞれ好みはバラバラでした。


あとch0(キック)については4拍目・8拍目だけ強くしてほしい、全部の拍を均一で、といった好みの違いもありました)


イベント全体のシステム構成

前回の記事にも書きましたが、システム構成はこんな感じになってました。


f:id:shu223:20140805084608p:image:w600


  • ダンサー用 app は母艦の MBP から OSC でコントロール
  • お客さん用 app は母艦が会場に流す BGM に埋め込まれた音響透かしにより、自動的に再生開始

あと、トラブル検知用に、ダンサーappからBLE接続状態を送信するようにしました。


母艦からのシステム全体の制御は真鍋さん作のMaxパッチで行っていて、照明の制御はDMXってやつらしいです。こちらも真鍋さんがコード書いてます。


f:id:shu223:20140814074402j:image:w300

(制御用パッチ。本番中の2曲目の最中に撮ったもの)


当日の様子

いままで自分がやってきた仕事と毛色が違って、その場限りの一発勝負なので、自分が出るわけでもないのに、それはそれは緊張しました。。練習やリハではBLE接続が切れたり、バッテリーが切れたりといろいろあったので。。


f:id:shu223:20140814072957j:image:w400

(オペレーション席)



結果的にはトラブルもなく、素晴らしいデモンストレーション *1 となりました。


f:id:shu223:20140814073027j:image:w400


ラストの、会場のBGMを完全に消して、ダンサーたちのステップと息づかいだけが聴こえる部分は神秘的ですらありました。



残りの時間は、キュレーターの難波さん+ダンサー佐山さん+制作の4人でのトーク。


f:id:shu223:20140814073055j:image:w400


壇上にいましたが、知らない技術や研究の話とかあって普通に聞いてておもしろかったです。


※観に来ていた友人が撮ってくれた写真なのですが、彼が座ってた席の都合上ステージ真横からの写真しかないので、真正面の写真をお持ちの方、ぜひご提供いただけると嬉しいです。



f:id:shu223:20140814081236j:image:w600

(撤収作業の後、そのまま会場にて打ち上げ)


真鍋さんについて

間近でお仕事させていただいて、いろいろと学びがありました。真鍋さんの仕事の特徴、印象に残ったエピソードなど。

切り替えが異常に早い

技術的にチャレンジングな案件を同時に何本もかかえながら、インタビューやTV取材、打ち合わせもひっきりなしにあって、いったいどうやってこなしているのか、不思議でしょうがなかったのですが、ライゾマオフィスでの動きを見ていて、ハッとしたことがありました。


何かのインタビューが終わり、「ありがとうございましたー」・・・席を立ち、自分の机に向かい、何かの箱をかつぐ・・・大きいテーブルの方へ・・・機材セットアップ開始・・・


インタビュー終わって、1秒の余韻にひたることもなく、席を立ったその足で次の実験へ移行してて、「これかー!」と思いました。僕ならコンビニにコーヒー買いに行って、立ち読みして、戻ってFacebookやTwitterみて、そのままインターネットの世界に吸い込まれ、数時間後にやっと仕事に戻る、ぐらいなのに。。

クレジットを大事にする

メディアとかは、とにかく有名な真鍋さんだけをフィーチャーしたがるわけですが(その方が楽だし、コンテンツ力高い)、そうならないよう注意喚起し、関わったメンバーをしっかり引き上げようとしてくれる印象があります。


今回の件も、iOS部分を手伝っただけの僕を、同列にクレジットしてくれたり、イベントのトークのときも元々真鍋さん、照岡さん、ダンサーの佐山さんだけがステージにあがる予定だったのを僕も上がるよう提案してくれたりしました。


そういう配慮は、あまり表舞台に出ることがないエンジニアとしてはとても嬉しいし、ぜひまたお仕事ご一緒したいと思うので、それが真鍋さんのまわりに各分野の一流クリエイターが集まっている理由のひとつかもしれません。

手を動かす

帰り道が一緒なので、会場でのリハ等のときはだいたい最終電車で一緒だったわけですが、そこから家に帰る真鍋さんを見たことがありません。だいたいそのあと打ち合わせが入ってて、スタジオとか、別の会場に向かわれます。あと、ギリギリまで練習に立ち会ってくれて、空港までタクシーで向かわれたりとか。


で、そんな超多忙な中でも、自分でコード書いたり、新しい技術の実験をしたり、ってことは絶対に欠かさない。


清水幹太さんとの対談で、

真鍋 さっき、幹太さんがわたしをうらやましいと言ってましたが、実はわたしにも同じような悩みがあるんですよ。担当する案件が増えて、自分で手を動かさない時間が長くなってきてるんです。また、優秀なメンバーが増えて来たので、わたしが直接作らなくても済むようになった。最初の設計以外はマネジメントばかりですね。このまま行ったらまずいかなと思ったので、わたし一人だけで動かすプロジェクトを作っていろいろと感触を確認しています。現場から離れて「上流」に行くと、クリエイターとしてダメになるんじゃないかという怖さは常にありますよね。

というくだりがありましたが、まさにこれを実践されている感じです。

現場で決まる

「直前に仕様変更が・・・」というレベルではなく、真鍋さんとの仕事の場合、ほとんどのことが現場でリアルタイムに決まっていくので、その場でパパッと要求に応える速さと引き出しの多さが要求されます。その場でできないなら、せめて代替案だけでもサッと出せる必要がある。


そういうスピード感、当日になって何が急に降ってくるかわからないスリル感もご一緒してて楽しい点のひとつでした。(現場仕事はどれもそういうものなのかもしれませんが。。)


まとめ

とにかく無事に終わってよかったです。SOUL FAMILYの皆様、真鍋さん、照岡さん、石橋さん、手話通訳の和田さん、象の鼻および運営の皆様、見に来てくださった方々、どうもありがとうございました!!!!


関連記事


*1:ちなみに「ライブパフォーマンス」とかではなく、「デモンストレーション」「プレゼンテーション」と銘打っているのは、まだプロジェクトとしては途上段階であり、今回は中間報告的な位置づけであるためです。

[雑記]とあるシングルスタックエンジニアの生存戦略

$
0
0

昨日『好きなことで生きるエンジニアを知る(Part2)』というイベントで登壇してきました。「どうやったらおもしろく働き続けられるか?」みたいなテーマなので本記事タイトルにある「生存戦略」とはちょっと違う印象を持たれるかもしれませんが、おもしろくないと生きていてつらいので、僕としては合ってるかなと。


もともとはスライドとか用意する必要なくて、聴講者含めてのディスカッション形式でやりましょうと主催の方には言っていただいてたのですが、僕の場合は準備なしでしゃべるとグダグダになるので、一応自分の考えぐらいは整理しとこう、ということでスライドを用意しました。



で、ここまで20分ぐらいで、あとは撤収までエンドレスで参加者の方々からの質問に答えていきつつ内容を補完する形式でした。


Q&Aのメモ

参考までに、参加者の方はフリーランスと会社員が半々ぐらい、エンジニア/非エンジニアの割合も半々ぐらいでした。


下記以外にもたくさんあったので、思い出したら追記していきます。


f:id:shu223:20140829182530j:image:w600

(当日のホワイトボード)


Q: お金は出ないけどおもしろい/スキルや実績は得られる仕事ばかり続くときはどうしてますか?

A: 基本的に、フリーランスとして受ける場合の「おもしろい仕事」「スキルや実績を得られる仕事」には、お金も自然とついてくると思っている。


例えば、WHILLみたいなプロダクトは、調達もしっかりできる企業じゃないと絶対につくれないし、良いメンバー(各分野のプロ)も集めてこれないといけない。Moffもしかり。


というわけで実際にはフリーになってからはお金の面でもとくに妥協はしていない。自分がお金の面にはこだわらず、スキルや実績を積んでいったのは主に会社員(カヤック)時代もしくは その前 の話。


Q: iOSだけじゃ厳しいんじゃないの?

A: そう思います。僕がやりたいのは「ずっとiOSで食べていくこと」じゃなくて「その時々の興味あることで食べていくこと」なので、時代の流れに合わせて興味も移っていって、やってることもシフトしていってると思います。


Q: 将来設計は?ずっとフリーランスでやっていくのか?

A: そこはとくに考えてないです。というより、そこを決めずにその時々の時流や心境の変化に応じて自分の立場も変えていくのが理想です。


Q: 相手の目利きはどうしてるのか?

(わらしべ長者方式で、間違った交換をしないという所で、相手のことを見抜く目利きが重要な気がするけど実際の所どうなのか?)


A: 自分は「初対面でその人がどんな人かわかる」みたいな能力は全然ない。ただ自分にとっておもしろい仕事を選んだ場合、それをやってる人もだいたい自分と合うことが多い。


Q: 奥さんに反対されないですか?

A: 奥さんは全然インターネットの世界や技術に興味のない人だが、日々、今はどんな人とどんな仕事やってて、何があったとかどう思ったとかを話すようにしている。


仕事について話すのはなかなか面倒なところもある(難しい)ので、そこをさぼってて、ある日突然「独立したい」とか言い出すとそりゃ不安にもなるのかなと。


うちの場合は日々の心境や状況を共有できているので、一見突飛な行動も自然な流れの中にあるから理解してもらいやすいのかなと思っています。


Q: 「できないブランディング」は最初から意識していたのか?

A: 最初は全然意識してなかった。新しい技術に取り組む腰が重いだけ。結果論として「できないメリット」もあったので、そういうことを後付けで意識するようになった。


Q: ブログの更新頻度は気にするか?どうテーマ選びしているか?

A: 更新頻度は気にしていないです。僕のブログは「固定読者が毎日見に来る」というタイプじゃなくて、技術記事はググって出てきたときに見られるものだし、海外に行ったとかの話 はシェアされてTwitterやFacebookのタイムラインから見に来てくれるものなので。


テーマ選びについては、自分が仕事でやっていきたい分野(例:BLE)についてはちょっとでもかじるだけでも積極的にブログに書いて、あんまりやりたくないところとかはノウハウあっても逆に書かなかったり、とかはあります。


始めた当初は読者もいなかったので、特に意識はしてなくて、日々の開発の中で出てくるメモをひたすらアップしてた感じです。


Q: ブログ書いてて途中で飽きることはない?

A: めちゃめちゃあります。しっかり書いてて途中で飽きてお蔵入りになる記事の方が、アップする記事の10倍ぐらいあると思います。


おわりに

この「わらしべ長者方式」は以前ブログに書いたときに全然反応なくて、唯一反応してくれたのが今回の主催の小山田さんで、個人的には「どのあたりが疑問に思ったのか/共感できなかったのか」ということを知りたかったので、今回のディスカッションベースの会は非常に有意義でした。


そもそも「わらしべ長者」っていうメタファーのチョイスが失敗してる気もする(もっといい案があればぜひお願いします)し、結局肝心なところは「がんばるしかない」としか言ってなくてあんまり参考にならない感もあります。


とはいえ僕がいまはわりと自由度高く好きなことをやって食べられるようになっているのは事実で、しかも 最初からプログラムがバリバリできたわけじゃない ので、他のみなさんにも参考になるような部分がきっとあるんじゃないかなーと思いつつ、こういうテーマでの話は今後もブラッシュアップしつつ続けていきたいと思っています。



で、キャリア繋がりで、来週9/6(土)にこんなイベントにもパネラーとして登壇します。


挑戦するエンジニアを応援する! 〜大企業を飛び出したエンジニアの実体験トークイベント〜 - 挑戦するエンジニアの応援チーム | Doorkeeper


あんまりストレートに言うのがはばかられるところもあるのですが、僕なりにこのイベントの趣旨を平たく言うと、「大企業を飛び出したいけど迷ってる方々 *1 の背中を押します」ということかなと。


パネルセッションだけじゃなく、ざっくばらんに話せるブースセッションもあり、ビールもでるそうなので、ぜひ!


*1:大企業じゃなくても、ちょっと思い切ったキャリアチェンジをしたい人

Viewing all 317 articles
Browse latest View live