読者です 読者をやめる 読者になる 読者になる

自宅プログラマーの憂鬱

Since 2013。個人でアプリ作っています。

正確なiPhoneのメトロノームアプリについて

ども。ちょっと開発に疲れたので、今日はメトロノームアプリのお話をさせて頂きます。

本日twitterを見ていたら「メトロノームはアプリで済まさず、ちゃんと買え!」みたいなのがあって、ちょっとムッとしたので反論です。信頼できないなどと、おっしゃる方がいらっしゃる。確かにいい加減なのあるのは否定しませんが、ちゃんと選べば正確なのがあるんです。私は、Smart Metoronomeを開発するにあたって50個のメトロノームを評価しましたので、iPhoneメトロノームアプリに関しては日本でも5本の指に入るくらい詳しいと思っています。今日は、その中でも代表的なの6つを選んで計測してみました。

<計測方法>

  • 120BPM
  • Beatが設定できるものは4/4拍子に設定


こんな感じ。

f:id:ihatomo:20161119134350p:plain
(クリックで拡大)

さて、拡大してみてみましょう。まずは3秒後のタイミング。1目盛りが1msです。

f:id:ihatomo:20161119134521p:plain
(クリックで拡大)

上ふたつが、正確で、その下2つは2msほど早いですが、許容範囲でしょう。
もう一箇所、10秒後を拡大してみましょう。同じく1目盛りが1msです。

f:id:ihatomo:20161119134906p:plain
(クリックで拡大)
上の2つは正確ですね。その下2つは5msほど早いですが、許容範囲でしょう。Bのふたつがほとんど同じタイミングでずれているのがわかりますが、これはiPhoneのハードウェアの特性によるものと考えています。Aはそれを補正しています。

私は、メトロノームアプリを正確性だけで分類すると、このABCの3種類に分けられると考えます。

A:正確なもの
B:間隔は一定だけど時間計測にわずかな誤差があるもの
C:揺らぐもの

AとBは、実用上の差異はありませんので、デザインや、使い勝手などでお好きなものを使えば良いと思います。ただ困ったことに、殆んどのメトロノームアプリはCに属しています。テンポ感覚は人それぞれかと思いますが、私は、1/100秒ずれると「あれっ?」って思います。なるべく正確なものを選んで、正しいテンポ感を身に着けたいですね。

尚、プログラムの内部的な話を少ししますと、恐らくAとBは基本的に同じ作りで、一番上のを作った感じだと、どれもハードウェアに直接クリック音を渡しており、時間計測をソフトウェアで行っていないと推測しています。そしてAは、若干それを補正しているだけ。だからBを補正するのは、実は簡単です。Cは、CPUでiPhone内のClockを見に行って、タイミングをとって音を鳴らしていると思われます。なので、CPUのタスク処理状況によって揺らぎが発生してしまいます。

というわけで、電子メトロノームを買うのも良いですが、アプリをバカにするのはやめて下さいね。
で、よかったらこれ使ってください。

AWS SNSにPHPでendPointを追加できない

またもやはまりまくり。
iPhoneへのPUSH通知にAWSSNSを導入していて、endPointの登録にAWS SDK for PHPを使用したのですが、はまりましたので共有します。解決策はこちらを参考にしました。

AWS SDK用のPHPスクリプトは以下で良いはずなのですが、エラーになります。

<?php 
require 'aws.phar';
use Aws\Sns\SnsClient;
 
$sns = SnsClient::factory(array(
            'version' => 'latest',  //これ入れないとエラー吐く
            'key'    => 'アクセスキーを入れる', //アクセスキー
            'secret' => 'シークレットキーを入れる', //シークレットキー
            'region' => 'ap-northeast-1'//地域コード
            ));
 
//デバイス(iPhone等)からデバイストークンを受け取る
$token = $_POST['token'];
 
//Application ARN:Amazon SNS上のAPP ARNを指定
$iOS_AppArn = 'arn:aws:sns:ap-northeast-1:1234567890:app/APNS_SANDBOX/hogehoge';
 
$options = array(
            'PlatformApplicationArn' => $iOS_AppArn,
            'Token' => $token,
            'CustomUserData' => "Test" //User Data
);
 
//エンドポイントをAmazon SNSに登録
$sns->createPlatformEndpoint($options);

?>

実行結果:404 Not Found、アクセスできてない

PHP Fatal error:  Uncaught exception 'Aws\Exception\CredentialsException'
 with message 'Error retrieving credentials from the instance profile metadata
 server. (Client error: `GET http://xxx.xxx.xxx.xxx/latest/meta-data/iam/
security-credentials/` resulted in a `404 Not Found` response:

で、アクセスキーとか、シークレットキーを設定する部分を以下の様に変更。

$sns = SnsClient::factory(array(
            'version' => 'latest', //これ入れないとエラー吐く
            'credentials' => [
                'key'    => 'AccessKey',
                'secret=> 'secret '],
            'region' => 'ap-northeast-1'//地域コード
            ));

これで、無事登録。どうやらパラメータがcredentials配下に下がったみたい。やれやれ。

キーチェーンアクセスから.p12が書き出せない

こちらを参照させて頂きました。

ios - iOSでプッシュ通知の証明書を.p12形式でexportしようとしたら.p12形式が選択できない - スタック・オーバーフロー

Push通知を行うにあたって、AWSSNSでAPNSを使おうと思ったのですが、SNSに証明書を設定するのに.p12形式の証明書をアップするのに、キーチェーンアクセスから.p12形式のファイルが書き出せなくて困ってました。答えは、以下の項目を"すべての項目"ではなくて、”自分の証明書"にすると書き出せました。めでたしめでたし。

f:id:ihatomo:20161108171321p:plain

iOSのPush NotificationでAppの有効な“aps-environment”エンタイトルメント文字列が見つかりません"となる

久しぶりのエントリーです。
しばらくtumblrに書いていたのですが、こちらに戻ってきました。

初めてアプリにPush通知機能を搭載しようとしたのですが、はまりまくりましたのでシェアします。搭載自体は、こちらを参考にしました。少し記事が古いためところどころ読み替えが必要ですが、そんなに混乱はなく実施できると思います。

iOSでプッシュ通知を実装する方法の超詳細まとめ(前編) | Lancork

で、この通りやってもタイトルの通り以下のエラーが消えない。

error => (NSError)Error Domain=NSCocoaErrorDomain Code=3000 "Appの有効な“aps-environment”
エンタイトルメント文字列が見つかりません" UserInfo={NSLocalizedDescription=Appの有効な
“aps-environment”エンタイトルメント文字列が見つかりません}

Google先生に聞くと、大抵Push Notificationを有効にしてプロビジョニングプロファイルを作り直せ、というのが解答なのですが、それもやった。何度もやった、、、お手上げ。仕方ないので、StackOverflowとかに投稿しようかと思った矢先、こちらをみつけました。

f:id:ihatomo:20161106131541p:plain

もうアホかと、、。 アプリ本体のTargetのCapabilitiesがOFFになってるじゃありませんか。ここをONにしてクリア! やれやれ。

iPhone動画カメラアプリは、撮ったファイルが自動で消えない

今作ってる動画カメラアプリですが、iTUNES Connectで申請まで終わって、やれやれ、ということで自分のiPhoneにローカルインストールして使っていたら、ストレージがいっぱいになったぞゴルァ!と怒られてしまいました。んなこたーないだろう!?とiPhoneのストレージ使用状況を見ると、何と私のカメラアプリが、数ギガにまで膨れ上がってるじゃないか!?ということで早速調べてみた。

このアプリは、明示的に「保存」しない限り、写真フォルダーに動画を保存しないつくりなのですが、それでも一時ファイルがどんどん残ってしまいます。なので消さないといけなかったのね。早速、申請を取り下げて修正をすることに。

//インスタンス変数として宣言
NSString *pathToVideo;

//録画が終わったら起動されるメソッド
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    NSURL *videoURL  = [info valueForKey:UIImagePickerControllerMediaURL];
    pathToVideo = [videoURL path];
    _videoURL = pathToVideo;
    //PickerControllerを閉じる
    [self dismissViewControllerAnimated:YES completion:nil];
    
//   取った画像の再生
    NSURL *url = [info valueForKey:UIImagePickerControllerMediaURL];
    playerItem = [[AVPlayerItem alloc] initWithURL:url];
    [playerItem addObserver:self forKeyPath:@"status" options:0 context:&ItemStatusContext];
    [[NSNotificationCenter defaultCenter]
     addObserver:self
     selector:@selector(playerItemDidReachEnd:)
     name:AVPlayerItemDidPlayToEndTimeNotification
     object:playerItem];
    player = [AVPlayer playerWithPlayerItem:playerItem];
    [playerView setPlayer:player];
    //再生開始
    [player play];
}


//必要なタイミングでこのメソッドを呼び出す
-(void) deleteFile
    {
    //ここで録画したファイルを消す
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:pathToVideo]) {
        NSError *error;
        // Attempt to delete the folder containing globalDel.videoPath
        
        if ([fileManager removeItemAtPath:[pathToVideo stringByDeletingLastPathComponent] error:&error] != YES)
        {
            NSLog(@"Unable to delete file: %@", [error localizedDescription]);
        }else{
            NSLog (@"消去成功");
        }
    } else {
        NSLog (@"消去失敗");
        
    }
}

何でクラッシュするの?

iPhoneアプリ、バージョンUPしたものがAPPストアでReady for saleになった。
早速喜んでDLして起動したら、、、 |)゚0゚(| ホェー!!


起動直後にクラッシュ!!


もちろん開発環境では問題なく動いてる。何でだよ!? 急いでAPPLEにはメールしたけど、こういう場合何かできることってあるのかなぁ。

Hours Install

UIが良いらしいのでiPhoneアプリのHours入れてみる。500円。

何時から何時まで何をやってたかLOGするアプリ。
なるほど、複雑な事やらせる割には直感的に操作できる。プリセットしたタスクをStart/Stopするだけ。
英語アプリだから英語で使うことにする。

ただ、これを何に活用するんだか、、、。