井原プロダクトのBLOG

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

最近のiPhoneの残念なところを何とかする

私は、iPhone3G以来10年iPhoneを使っている生粋のiPhoneユーザーです。現在XSを使っています。素晴らしいです。素晴らしくて困るくらいです。高級感に溢れ過ぎて、手にしたときに若干の緊張が走るのです。100円のボールペンで気楽に字を書きたいのに、常に3万円のペリカンの万年筆で字を書いているようなオーバースペック感。スマホなんてものは、もっとラフにガシガシ使いたいのにね。

基本裸族です。カバーなんかつけたことありません。傷ついたっていいじゃないですか。物を大事にする心より、傷なんか気にしない大らかさ、おおげさに言うと人間の大きさをアピールしたいです。というか、元々カバーつけないで使うように設計されているんじゃないのかな、って思っていたら最近は、当のAppleさんまで純正のカバーを売ってるからねぇ。ジョブズが生きていたら嘆き悲しむだろうなぁ。

そんな私ですが、ついにバンパーをつけてしまいました。なぜって、iPhoneXSが使いづらいからです。

f:id:ihatomo:20190207090950j:plain
iphoneX/iPhone Xs アルミ製メタルバンパー【SWORD】炭素繊維 カーボンファイバー ハイブリッドケース 最新型【純正・真正品】 (iphoneX/iPhone Xs, シルバー)

何が使いづらくて、何故バンパーなのか?っていう話ですが、まずはiPhoneSEを見てください。f:id:ihatomo:20190204091806j:plain
注目して欲しいのはボタンの位置です。スリープボタンは上部に、ボリュームボタンはサイドにあります。そしてボリュームがない方のサイドにはボタンは配置されていません。このことによって、ボリュームの大小を調節するときにスリープを押してしまうという操作ミスはまずありえません。

ところが何ということでしょう。iPhone6以降スリープボタンはボリュームボタンと反対サイドに配置されてしまい、これによってボリュームを操作しようと思って誤ってスリープを押してしまうことが多発することになってしまいました。それはもうしょっちゅう。iPhoneを横にしてYouTubeを観ているときとか、横にしているから間違えるだけじゃなくて、縦使いでもVolumeボタンを押すときって反対サイドも持ちつつそこを支点に押すので、すぐスリープを触っちゃう。地図みてて一瞬ポケット入れて出そうとするときも押しちゃう。最悪なのは部屋を暗くして布団の中でYouTube見てるときで、ボリュームを操作しようとしてアプリを落としちゃうと再起動するときに部屋が暗いから顔認証できなくてパスコード入力するはめになる。そう、この面倒臭さって顔認証とセットのダブルパンチなのだ。

というわけで、何とかこれを解決すべくスリープボタンを押しにくくできないかなぁと考えた挙句、バンパーのスリープボタンを削ってみることにしました。写真はすでに削ったあとのものですが、スリープボタンがほとんど出っ張っていないのがわかると思います。

f:id:ihatomo:20190207093827j:plain

こうやってスリープボタンを一度はずして紙やすりでゴシゴシと。

f:id:ihatomo:20190203163140j:plain


これによってスリープボタンは、タッチしたくらいでは押せなくなって誤操作はなくなりました。でも、全く押せないかというとそんなことはなくて、ギュっと押せば押せます。ボリューム操作時の誤操作は防げて、かつスリープも可能。めでたしめでたしかと言うと、やっぱりバンパーつけるのやだなぁ。裸の方が手になじむし、スリープやりづらいし、何よりこのバンパー、アンテナ感度が一本減ります。というわけで新型は上部が肉抜きされてますね。


やれやれ

MacでFTP難民になった

はい、MacOSのHigh Sierraでは、ターミナルからFTPコマンドを打つことができなくなりました。

f:id:ihatomo:20190125101509p:plain


そのせいなのか、なぜかFTPクライアントソフトのCyberduckちゃんも使えなくなっていて、Loginはできて、サーバー側のDirectoryも見えるのだけど、なぜかファイルのUploadが完了しない、、。Cyberduckつかえない、ターミナルでftp打つこともできないとなると、、。こういうときはサーバー側にsftpを組み込んだりCyberduckのアクセスLogを見たりするのが定石だけど、正直面倒臭いしftp周りの設定やプロトコルに興味もないし、元々Cyberduckは処理が遅くて不満があるしで、他のFTPソフトを探して試してみることにしました。

というわけで、これでできた。Yummy FTP

https://itunes.apple.com/jp/app/yummy-ftp-pro/id492068728?mt=12&at=10l8JW&ct=hatenablog


って、あれれ APP Storeだと1,800円だ(2019/1/25現在)。昨日$29.99 PayPalで払っちゃったし。

Yummy FTP for Mac - Download

こちらだと無料でソフトのDLが可能なのですが、しばらく使っていると使用期限が過ぎて課金しないと使えなくなります。そこで決済すると上記金額でした。というわけで、有料版へ移行するときはAPP Storeもチェックしてください。

やれやれ。

iPhoneの3D Touchを組み込んでみた

youtu.be

こんにちは。

年末から、ずっとSmart Metronomeのアップデートを行っておりまして、今回の変更は、収益性改善の部分と、それだけではナンなので軽めの改修を入れようかなと、メイン画面のテンポを変化させるプラスとマイナスボタンに3D Touchを組み込んでみました。3D Touchは、iPhoneXRでは採用されなかったりして、色々な憶測が飛び交っている機能なのですが、確かに硬いガラスの表面を押しているだけなのに、強く押したり弱く押したりによってアナログ的な表現ができます。但し、実際に凹んだりするわけではないので、強さのフィードバックは弾力では返ってきません。では代わりにどうするか?というとホームボタンの様にコツンという振動を返します。これによってあたかも、ボタンを押したような錯覚が起きます。

この機能は、確かに素晴らしいのですが、欠点は画面上のボタンが強く押し込めるものなのか、3D Touchを実装しているボタンなのかどうかが見た目で全くわからないことです。しかも大抵のボタンは、タップするとその機能を果たすのでユーザーはイチイチアプリ上のボタンを強く押してみたりはしません。スーパーマリオの隠れコインのように全部試すモチベーションは無いのです。なので大多数のiPhoneユーザーは、iPhoneのLEDライトが4段階に調整できる事を知らないでしょう。これでは隠しコマンドです。

f:id:ihatomo:20190114163535p:plain


というわけで、Smart Metronomeでは、バージョンアップ情報として説明動画を載せようと思っているんだけど、いざ動画作ろうと思ってもiMovieじゃダメですね。動画上に動画を重ねられないから上の動画に固定の文字を入れることはできても、タップしているという事をアニメで伝えることができない。というわけで、FinalCutProX買おうかどうか迷っているところです。動画に関しては他にもやりたい事があるので、約35KJPYの投資になってしまうけれどまぁいいかなと。

ということで、次のバージョンアップを楽しみにしていてください。尚、3D Touchは、iPhone6S以降でしたっけ。それ以前のiPhoneと何故かiPhone XRでは使えません。


上記動画のソースコード公開します。ForceTouchを搭載していない場合は、LongTapが動作する様になっています。

[2019/2/7 追記] GitHubにソース公開しました。こちらを参照ください。
blog.hatena.ne.jpihatomo.hatenablog.com

//追記ここまで

#pragma mark - plus/minus Button


@property UISelectionFeedbackGenerator *selectionFeedbackGenerator;
@property UIImpactFeedbackGenerator *impactFeedbackGenerator;

NSInteger taplevelSave;


-(void) preparePlusMinusButton {
    
    _plusButton.exclusiveTouch = YES;
    _minusButton.exclusiveTouch = YES;
    
    //ボタンタッチ
    [_plusButton addTarget:self action:@selector(buttonTappedHandlerUp:) forControlEvents:UIControlEventTouchDown];
    [_minusButton addTarget:self action:@selector(buttonTappedHandlerDown:) forControlEvents:UIControlEventTouchDown];
    
    //
    if ([self isForceTouchAvalable]){
        //forceTouchの処理設定
        [_minusButton addTarget:self action:@selector(getButonForce:withEvent: ) forControlEvents: UIControlEventAllTouchEvents];
        [_plusButton addTarget:self action:@selector(getButonForce:withEvent: ) forControlEvents: UIControlEventAllTouchEvents];
        //ボタンタッチアップ
        [_plusButton addTarget:self action:@selector(touchUpInside) forControlEvents:UIControlEventTouchUpInside];
        [_minusButton addTarget:self action:@selector(touchUpInside) forControlEvents:UIControlEventTouchUpInside];
        //FeedBack
        _selectionFeedbackGenerator = [[UISelectionFeedbackGenerator alloc] init];
        _impactFeedbackGenerator = [[UIImpactFeedbackGenerator alloc] init];
        [_selectionFeedbackGenerator prepare];
        [_impactFeedbackGenerator prepare];
    } else {
        //ボタンの長押し処理設定
        UILongPressGestureRecognizer *gestureRecognizer1 = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressedHandlerDown:)];
        [_minusButton addGestureRecognizer:gestureRecognizer1];
        UILongPressGestureRecognizer *gestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressedHandlerUp:)];
        [_plusButton addGestureRecognizer:gestureRecognizer];
    }
 

}

// ***** 通常のタップ時の処理 *****
-(void)buttonTappedHandlerUp:(UIButton *)button
{
    if (_tempo < 999 ){
        _tempo ++;
        if (_tempo == 300){
            [self divideSet_withoutSound:1];
        }
    }
    [self tempoSet:(float)_tempo];
}


-(void)buttonTappedHandlerDown:(UIButton *)button
{
    if (_tempo > 999){
        _tempo = 999;
    }
    if (_tempo > 1){
        _tempo --;
    }
    [self tempoSet:(float)_tempo];
}


// ***** 長押し関連処理 *****
-(void)longPressedHandlerUp:(UILongPressGestureRecognizer *)gestureRecognizer
{
    //NSLog(@"%s",__func__);
    switch (gestureRecognizer.state) {
        case UIGestureRecognizerStateBegan://長押しを検知開始
        {
            buttonCounter = 0;
            taplevelSave = 0;
            float interval = 0.1;
            NSLog(@"UIGestureRecognizerStateBegan");
            
            buttonTimer = [NSTimer
                           scheduledTimerWithTimeInterval:interval
                           target:self
                           selector:@selector(tempoUpForLogTap)
                           userInfo:nil
                           repeats:YES
                           ];
            [buttonTimer fire];
            
        }
            break;
        case UIGestureRecognizerStateEnded://長押し終了時
        {
            [Metronome change:self.tempo];
            if (_tempo > 299 || divide !=1){
                [self divideSet_withoutSound:1];
            }
            [buttonTimer invalidate];
            //値の保存
            NSUserDefaults *temposave = [NSUserDefaults standardUserDefaults];
            [temposave setFloat:_tempo forKey:@"tempo"];
            buttonCounter = 0;
        }
            break;
        default:
            break;
    }
}


-(void)longPressedHandlerDown:(UILongPressGestureRecognizer *)gestureRecognizer
{
    //NSLog(@"%s",__func__);
    switch (gestureRecognizer.state) {
        case UIGestureRecognizerStateBegan://長押しを検知開始
        {
            buttonCounter = 0;
            taplevelSave = 0;
            float interval = 0.1;
            NSLog(@"UIGestureRecognizerStateBegan");
            
            buttonTimer = [NSTimer
                           scheduledTimerWithTimeInterval:interval
                           target:self
                           selector:@selector(tempoDownForLongTap)
                           userInfo:nil
                           repeats:YES
                           ];
            [buttonTimer fire];
            
        }
            break;
        case UIGestureRecognizerStateEnded://長押し終了時
        {
            [Metronome change:self.tempo];
            [buttonTimer invalidate];
            //値の保存
            NSUserDefaults *temposave = [NSUserDefaults standardUserDefaults];
            [temposave setFloat:_tempo forKey:@"tempo"];
            buttonCounter = 0;
        }
            break;
        default:
            break;
    }
}

-(void)tempoUpForLogTap{
    //最初の5回はゆっくり、その後早く
    if (buttonCounter < 20){
        if (_tempo < 999) {
            _tempo = _tempo + 1;
        }
    } else if (buttonCounter < 65){
        if (_tempo < 997) {
            _tempo = _tempo + 2;
        } else if (_tempo < 999){
            _tempo ++;
        }
    } else {
        if (_tempo < 995) {
            _tempo = _tempo + 5;
        } else if (_tempo < 999){
            _tempo ++;
        }
    }
    buttonCounter ++;
    [self tempoSetEnd];
    
}

-(void)tempoDownForLongTap{
    //最初の5回はゆっくり、その後早く
    if (buttonCounter < 20){
        if (_tempo > 1){
            _tempo --;
        }
    } else if (buttonCounter < 65){
        if (_tempo > 2) {
            _tempo = _tempo - 2;
        } else if (_tempo > 1){
            _tempo --;
        }
    } else {
        if (_tempo > 5) {
            _tempo = _tempo - 5;
        } else if (_tempo > 1){
            _tempo --;
        }
    }
    buttonCounter ++;
    [self tempoSetEnd];
}


-(void) tempoSetEnd {
    int tempoInt = (int) _tempo;
    _tempo = tempoInt;
    NSString *tempotext = [NSString stringWithFormat:@"%d", tempoInt];
    _tempoLabel.text = tempotext;
    [self tempoMarkSet:_tempo];
    [Metronome change:self.tempo];
    //sliderのセット
    _pendlumSlider.value = _tempo;
}


//以下はfourceTouchの処理

-(void)getButonForce : (NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    //fourceTouchされたときに呼ばれる
    UITouch *touch = [[event allTouches] anyObject];
    float force = touch.force;
    float max = touch.maximumPossibleForce;
    float level = 0;
    if (max !=0) {
        level = force/max;
    }
    if (taplevelSave == 0){
        //buttonCounterのクリア
        buttonCounter = 0;
        float interval = 0.08;
        NSLog(@"%@", touch.view);
        if (touch.view == _minusButton){
            buttonTimer = [NSTimer
                           scheduledTimerWithTimeInterval:interval
                           target:self
                           selector:@selector(tempoDownForForceTap)
                           userInfo:nil
                           repeats:YES
                           ];
            [buttonTimer fire];
            buttonCounter ++;
            taplevelSave = level;
            //NSLog (@"Force Tapped %ld",(long)buttonCounter);
        } else if (touch.view == _plusButton) {
            buttonTimer = [NSTimer
                           scheduledTimerWithTimeInterval:interval
                           target:self
                           selector:@selector(tempoUpForForceTap)
                           userInfo:nil
                           repeats:YES
                           ];
            [buttonTimer fire];
            buttonCounter ++;
            taplevelSave = level;
        }
    }
    if (level > 0.7){
        //最強に押されている状態
        if (taplevelSave !=2){
            [UIView animateWithDuration:0.1f
                             animations:^{
                                 touch.view.transform = CGAffineTransformMakeScale(1.4, 1.4);
                             }];
            [_impactFeedbackGenerator impactOccurred];
            taplevelSave = 2;
        }
    } else if (level > 0.03) {
        //軽く押されている状態
        if (taplevelSave !=1){
            if (taplevelSave  == 2){
                [_impactFeedbackGenerator impactOccurred];

            }
            [UIView animateWithDuration:0.1f
                             animations:^{
                                 touch.view.transform = CGAffineTransformMakeScale(1.2, 1.2);
                             }];
            taplevelSave = 1;
        }
    } else {
        //ほとんど触ってるだけ(止める)
        [self touchUpInside];
        taplevelSave = 0;
    }
}

-(void) tempoUpForForceTap  {
    //NSLog (@"Tempo Up %ld",(long)taplevelSave);
    if (buttonCounter < 4){
        //最初の0.5秒は何もしない
        buttonCounter ++;
    } else {
        int x = 0;
        //tapの強さによって加速度を変える
        if (taplevelSave == 1){
            x=1;
        } else if (taplevelSave == 2){
            x = 10;
        }
        if (_tempo < 999 - x ){
            if (buttonCounter % 2 == 0) _tempo = _tempo + x;
            if (x==10){
                [_selectionFeedbackGenerator selectionChanged];
            }
        } else if (_tempo < 999) {
            _tempo = _tempo + 1;
        }
        buttonCounter ++;
        [self tempoSetEnd];
    }
}

-(void) tempoDownForForceTap  {
    //NSLog (@"Tempo Up %ld",(long)taplevelSave);
    if (buttonCounter < 4){
        //最初の0.5秒は何もしない
        buttonCounter ++;
    } else {
        int x = 0;
        //tapの強さによって加速度を変える
        if (taplevelSave == 1){
            x=1;
        } else if (taplevelSave == 2){
            x = 10;
        }
        if (_tempo > 1 + x ){
            if (buttonCounter % 2 == 0) _tempo = _tempo - x;
            if (x==10){
                [_selectionFeedbackGenerator selectionChanged];
            }
        } else if (_tempo > 1) {
            _tempo = _tempo - 1;
        }
        buttonCounter ++;
        [self tempoSetEnd];
    }
}


-(void)touchUpInside  {
    //NSLog (@"ボタンから指を離した");
    if ([buttonTimer isValid]){
        [buttonTimer invalidate];
    }
    [UIView animateWithDuration:0.1f
                     animations:^{
                         self->_plusButton.transform = CGAffineTransformMakeScale(1.0, 1.0);
                         self->_minusButton.transform = CGAffineTransformMakeScale(1.0, 1.0);

                     }];
    
    //値の保存
    NSUserDefaults *temposave = [NSUserDefaults standardUserDefaults];
    [temposave setFloat:_tempo forKey:@"tempo"];
    buttonCounter = 0;
}


-(BOOL)isForceTouchAvalable{
    NSString *strSystemVer = [UIDevice currentDevice].systemVersion;
    NSLog(@"version: %@", strSystemVer);
    double version = strSystemVer.doubleValue;
    if (version >= 9.0) {
        NSLog(@"ForceTouchCapability %zd",self.traitCollection.forceTouchCapability);
        if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {
            return YES;
        }
    }
    return NO;
}

【新版】UI GRAPHICS 成功事例と思想から学ぶ、これからのインターフェイスデザインとUX

今年もよろしくお願いします。

新年にあたり良いことがひとつ。何とHuffpostさんに@micorunさんと共同開発のアプリが紹介されました。Huffpostさんありがとうございます。これを機に日本の睡眠不足解消に貢献できたら嬉しく思います。

www.huffingtonpost.jp


さて今年ですが、やることを3つ決めています。どれもアプリに関することなのですが、1つ目はSmart Metronomeを再デザインすること、2つ目と3つ目は新アプリをリリースすること。というわけで、新年一冊目に読む本はこちらにしました。

【新版】UI GRAPHICS 成功事例と思想から学ぶ、これからのインターフェイスデザインとUX

【新版】UI GRAPHICS 成功事例と思想から学ぶ、これからのインターフェイスデザインとUX

  • 作者: 安藤剛,水野勝仁,萩原俊矢,ドミニク・チェン,菅俊一,鹿野護,有馬トモユキ,渡邊恵太,須齋佑紀/津?将氏,庄野祐輔,藤田夏海,塚田有那,増川草介??栂木一徳
  • 出版社/メーカー: ビー・エヌ・エヌ新社
  • 発売日: 2018/10/19
  • メディア: 単行本
  • この商品を含むブログを見る

Smart Metronomeは、iOS7のフラットデザインの潮流が来たときに大きくリデザインして、そのままになっています。その後、機能面のアップグレードや、UXの統一みたいな事は行ってきたものの、今となっては古く感じられる方も多いのではないかな。私自身もiPhoneXSを買って使っていると、デバイスの性能やOSの世界観にそぐわなくなっている事を感じています。でも、それって何がいけないんだろう? どうすれば良いんだろう?という問いに対して、答えやヒントが沢山載っていました。一番古めかしいのは、動作が直線的な事ですね。ボタンをタップすると別の画面にパって切り替わる。こういうのって最近では、びよーんと画面が現れて来て、現画面上に立体的に重なるように出現するんですよね。しかも途中でやっぱりやーめた、とかもできる。改善ポイントをざっくり箇条書きにすると

  • 途切れない操作感
  • 0か1ではない中間の動作を見せる
  • 操作時のユーザー心理をキャッチアップして小さな喜びを与える
  • つまりアニメーションや振動などで効果的なユーザ体験を生み出す
  • アイコンも大事
  • 2次元を積み重ねて3次元を作る

こんなところかな。既存アプリの例が豊富に掲載されているので、それを眺めているだけでも取り入れるべき課題が沢山みつかるという便利な本でした。早速色々なUIを試してみたいと思います。

あ、あとこれも観ました。

【Develop】マテリアル デザインでよりよいユーザー体験を実現しよう
www.youtube.com


ではでは。

Smart Metronomeがバックグラウンド再生できる様になりました

画面を消しても音が出ます!

f:id:ihatomo:20181124112413p:plain


これあんまりやりたくなかったんですよねぇ。消してる間は広告見なくなるから。なんてケチくさい理由だけじゃなくて、技術的にもできなかったんです。アプリ落としても鳴るのはできるけど、スリープモードにして画面を暗くすると何故か止まってしまう。なので、ご要望は多かったもののバックグラウンドで使いたいなら他のを使ってもらえばいいや、なんてほったらかしていたわけ。

ところが、こちらのtweetがきっかけで状況が一転してしまった。


寝るときにメトロノームの音を聞くとすぐに眠れるという話が拡散して、Smart Metronomeが沢山DLされることに。寝るときに使うのであれば、画面消して音だけ聞きたいですよねぇ。ということで、沢山の「バックグラウンドで再生できないのかよ!?」という誹謗中傷ご要望メールを頂くことに。

結局、画面消すと止まる問題は Stackoverflowの過去問にあったので、できる様になりました。というわけで、これからも便利使って下さい。

何で止まってしまっていたかというと、スリープモードではAudioQueueのバッファサイズを拡大しないとイケなかったみたいです(理由はよくわかりません)。でも単純にバッファサイズを大きくすると、今度は振り子が音と同期しなくなるため、フォアグラウンドからバックグラウンドにまわったら一旦止めてAudioQueueのバッファを大きくして再スタート、バックグラウンドからフォアグラウンドに戻るときもリスタートしています。これは今のところ未解決課題。

あと予告ですが、次のバージョンアップでは変拍子系を強化します。どういうUIにしようかとずっとずっと悩んでいたのですが、さっきローソンの一口焼き芋を食べていたときに素晴らしいアイディアが降ってきました。今からスケッチブックにお絵かきします。

Smart Metronome

Smart Metronome

  • Tomohiro Ihara
  • ミュージック
  • 無料

リム・カーワイ監督作品 どこでもない、ここしかない

バルカン半島を旅しながら、現地の友人を俳優に仕立て上げ、脚本なし、カメラマンと音声さん各1名という最低限のスタッフで映画なんか作れるもんなんだろうか?と興味津々で観てきましたところ、何とちゃんと映画になっていました。その企画力と行動力にびっくり。

この映画の背景は結構複雑で、主人公はマケドニアにすむトルコ系イスラム教徒。といってもピンと来る人は少ないと思うけど、マケドニアは15世紀より長い間オスマン帝国により支配されていたものの、2つの大戦を経て現在は独立。つまりトルコ系はマイノリティであるらしいのだが、そういう事はあまりどうでも良くて、この男、ビジネスやり手で女好きのどうしようも無い男として描かれる。ストーリーも夜な夜な女の子をおっかける旦那に愛想をつかせた奥さんが出ていくという、非常にシンプルなもので、全体を流れる時間もゆったりしているのだが、奥さんを追っかける距離は、マケドニアからクロアチアを経由してアルバニアへとアドリア海沿岸を大きく移動している。一体旅行がしたかったのか、撮影がメインだったのかよくわからない状況で生まれた映画である。

でも、なんだかそこがいい。普通の映画ならここでカット!となる様な場面でも、あと何秒かその場の描写が続く。そのため会話がなくなった後の気まずい時間とか、単にぼーっと流れる時間とか、その場の空気感をリアルに体験できる。例えば、妻のウーダンがベランダで夕日をみながら母親と電話するシーンがあって、ストーリー的にはその会話の中で「今夜は夫と外食することになっているの」っていうのが観客に伝わればよいのだけど(そして夫は帰ってこない)、そのベランダから見る夕日に染まる建物を見ながら階下の街の騒音を聞いているだけで、なんだかそこに旅している気になれるのだ。そういうシーンが、この映画には沢山あって旅愁を誘う。ストーリーのシンプルさや、ところどころわかりにくい所(結婚式のシーンで花嫁が出てきたと思ったら主人公の奥さんだったとか)、こういうのは撮影事情にもよるのだけれど、逆にそういう制限をしてよくここまで映画に仕上げたリム監督の手腕と情熱に感服するのである。そういう映画です。


そして、リム監督はあまりプライベートを語らないので本人の恋愛事情はよくわからないのだけど、海辺のデートシーンとか、クライマックスのシーンとか、あとオープニングとエンディングでオチをつくっているところとか、意外とロマンチストだなぁと。今度会ったら各国を旅してどんな出会いを経験してるのか聞いてみたいわ。




nowhere2018.themedia.jpnowhere2018.themedia.jp


大阪が舞台の「Fly Me To Minami 恋するミナミ」、香港を舞台にした「マジック&ロス」など、世界各国で映画制作活動をおこなうマレーシア出身の映画監督リム・カーワイが、妻に逃げられた男の物語を軸に、東ヨーロッパで現地の人びとと即興で作り上げた異色ドラマ。バルカン半島スロベニアの首都リュブリャナ。近年の観光と不動産ブームは、ゲストハウスとアパートメントを経営するフェデルに経済的な成功をもたらした。イスラム教徒でありながら、ゲストハウスに宿泊した女性や知人の彼女にまで手を出す女癖が悪いフェデルに、妻のヌーダンは愛想を尽かして家を出て行ってしまう。ようやく妻の大切さに気付いたフェデルは、ヌーダンを取り戻すためにマケドニアの田舎町へ向かうが……。

どこでもない、ここしかない
No Where, Now Here
2018/スロベニアマケドニア・マレーシア・日本合作
配給:Cinema Drifters

ihatomo 16分前

ついにアプリの月間インプレッションが1000万を超えました

うぁーい!

当面の目標であった、バナー広告の月間表示回数が1,000万を超えました。ひとえにユーザーの皆さん、応援してくださる皆さんのお陰です。ありがとうございます(涙)

f:id:ihatomo:20181103125549p:plain

こちらが、2013年6月にリリースしてからの歩み。ところどころ凹んでいるのは、表示時間の設定を変えているためだったりします。最初の頃は40秒で、後に60秒に変えたり戻したり、最近はずっと「自動」にしています。注目して頂きたいのは、最初の2年間は全く収入が無かったということ。それでもUI, UX, 配色など勉強して少しずつ改良を重ねるにつれ、DLも増え、APP Storeの検索順位も上位になり、ついに1位を獲得してからはグングン伸びています。嬉しい限りです。この線が更に伸びて行ったら来年の今頃はどうなることでしょう、頬がゆるみますね。

今まで、アプリ本体のクオリティの向上に注力していて、マネタイズに関してはadMob入れてほったらかしという状況だったのですが、それももったいないので他のアイディアも試してみたいと思います。というのも、一日に数万人という方が使って下さるのですが、バナー広告のクリック数はその1/10以下。つまり9割の方からは1円の収益も上がっていないわけで、これを何とか開拓できないものかなぁ、、、と。もちろんユーザビリティを損ねてはいけないので、その当たりはリワード等を考えて行きますがね。

どうぞ、今後ともよろしくお願いいたします。