【Xcode】Apple Watch用アプリのテスト(1)

【Xcode7.2 + MacOX10.11.2 + watchOS 2】
Apple Watch用アプリを試してみました。実機がないのでSimulatorで確認。

いろいろ探してみたけど、見た中ではこの記事が一番わかりやすかった。

・簡単な Apple Watch アプリを初めて作ってみる – Apple Watch アプリプログラミング –

Apple Watchアプリは、必ず親となるiPhoneアプリがあって、その子としてWatchKit App を作成するということのようです。

このサイトの通りで基本的に問題ないのだけれど、唯一違うのはwatchOSが2にバージョンアップされているので、プロジェクトエディターの追加ボタンから、Apple Watch のWatchKit App を選択するところで、選択肢が2つに増えているところ。ここでは左(watchOS 2)を選択。

WatchKit Appが、watchOS 2とwatchOS1の2種類あるある。
WatchKit Appが、watchOS2とwatchOS 1の2種類ある。無印がwatchOS2用。

もう1点、Simulatorで実行時に「”Install of Apple Watch Application never finished” 」というエラーが出たこと。これは、iPhone側のSimulatorでWatchアプリから、該当アプリの設定を開いて”Show App on Apple Watch”のスイッチを一度切ってから入れ直せばOKでした。詳しくは下記リンクで。

ios – “Install of Apple Watch Application never finished” Error when deploying watch kit app to device – Stack Overflow

これでSimulator上でApple Watchアプリの確認ができました。

【Xode】NavigationController配下にTabBarControllerを組み込む

【Xcode6.2 + iOS 8.4(iPhone5) + MacOX10.9.5】

文字通りのことをやろうと思ったんだけど、なかなかいい例がなかったのでメモ。

TabBarControllerとNavigationContorollerの組み合わせ例はいくつかあったんだけど、大抵がTabBarControllerをベースにして、子にNavigationContorollerを使うというパターン。

今回やりたかったのは、NavigationContorollerをベースにして、その配下でTabBarControllerを使うパターン。アプリの設定画面部分だけをTabBarControllerにするようなイメージです。

それから前提として「Viewは、プログラム生成ではなくStoryboardに配置する」ということ。AutoLayoutを使うことを考えると、レイアウトはStoryboard、処理はコードで分けるのがいいんじゃないかと。

Storyboardの構成はこんな感じです。
storyboard

・ViewController
・SettingViewController
・TimeSettingViewController
・SpeedSettingViewController

この4つは、それぞれ同名のカスタムクラスを作ってStoryboardで割り当てています。ViewControllerがrootControllerになっていて、ボタンタップで2つのタブ(TimeSettingViewController, SpeedSettingViewController)を持つTabBarController(SettingViewController)を呼び出す構成です。

※ちなみにTabBarControllerを配置すると自動的に接続されるSegueは削除してあります。その設定もコード上で試してみたかったので。

で、まずはUITabBarControllerの定義。どこで使うにせよ、これはAppDelegateの中に書くのが定石らしい。

【AppDelegate.h】
・Storyboardの各Viewを参照するので、その定義ファイル(.h)のimportと保存するUITabBarControllerの定義を追加する。

#import <UIKit/UIKit.h>
#import "SettingViewController.h"
#import "TimeSettingViewController.h"
#import "SpeedSettingViewController.h"

@interface AppDelegate : UIResponder <UIApplicationDelegate,UITabBarControllerDelegate>
{
    UITabBarController *myTabBarController;
}

@property (strong, nonatomic) UIWindow *window;
@property (nonatomic,strong) UITabBarController *myTabBarController;

@end

【AppDelegate.m】
・あとで参照する可能性もあるので、各タブのcontrollerも一応定義しておく。
・UITabBarController の生成は、didFinishLaunchingWithOptionsで行う。
・tabControllerの切替イベント(shouldSelectViewController, didSelectViewController)もココに定義。

#import "AppDelegate.h"

@interface AppDelegate ()

@end

@implementation AppDelegate
{
    TimeSettingViewController *TimeSettingVC;
    SpeedSettingViewController *SpeedSettingVC;
}

@synthesize myTabBarController;


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    //UITabBarControllerを生成(storyboard上のUITabBarControllerを指定)
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    myTabBarController = [storyboard instantiateViewControllerWithIdentifier:@"SettingVC"];
    
    //各タブ用UIViewControllerを生成(storyboard上のUIViewControllerを指定)
    TimeSettingVC = [storyboard instantiateViewControllerWithIdentifier:@"TimeSettingVC"];
    SpeedSettingVC = [storyboard instantiateViewControllerWithIdentifier:@"SpeedSettingVC"];
    
    //UITabBarControllerに各タブ用UIViewControllerを設定
    NSArray *controllers = [NSArray arrayWithObjects:TimeSettingVC,SpeedSettingVC, nil];
    [myTabBarController setViewControllers:controllers animated:YES];
    
    //デリゲートの設定
    myTabBarController.delegate = self;
    
    //初期表示のタブを指定
    myTabBarController.selectedViewController = myTabBarController.viewControllers[1];
    
    NSLog(@"--array: %@",myTabBarController.viewControllers);
    NSLog(@"--selectedViewController: %@",myTabBarController.selectedViewController);
    NSLog(@"--index: %d",myTabBarController.selectedIndex);

    return YES;
}

-(BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
     NSLog(@"--tabBarControllerを切り替えます!");
    NSLog(@"--selectedIndex: %d",tabBarController.selectedIndex);
    NSLog(@"-- vc: %@",viewController);
    
    return YES;
}

-(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
    NSLog(@"--tabBarControllerが切り替わった!");
    NSLog(@"--selectedIndex: %d",tabBarController.selectedIndex);
    NSLog(@"-- vc: %@",viewController);
}

@end

※22行目〜28行目までは、tabBarControllerに各タブを定義する処理なので、Storyboard上でSegueが定義されている場合は不要。

ここでのポイントは、AppDelegateからStoryboardを参照するには、storyboardWithNameを使わないといけないということ。各Viewからなら、self.storyboardでいけるんだけど。

【参考】

次にtabBarContorollerを呼び出す処理を書きます。viewControllerにボタンを配置して、そこからリンクします。

【ViewController.h】
・AppDelegateをimport。
・showSettingViewはボタンタップ時の処理。

#import <UIKit/UIKit.h>
#import "AppDelegate.h"

@interface ViewController : UIViewController

- (IBAction)showSettingView:(id)sender;

@end

【ViewController.m】
・AppDelegateを参照してtabBarControllerを取得して、pushViewControllerで表示する。

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

- (IBAction)showSettingView:(id)sender {
    //AppDelegateを参照して、myTabBarControllerを呼び出す
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    [self.navigationController pushViewController:appDelegate.myTabBarController animated:YES];
}

@end

iOS View Controller カタログ(PDF)によれば・・・

Tab Barインターフェイスを作成する前に、その使い方を決定する必要があります。Tab Barインターフェイスはデータに対して支配的な構成となるため、用途は以下に限定されます。
・ウィンドウのルートView Controllerとして追加する。
・Split Viewインターフェイスの2つのView Controllerの1つとして追加する。(iPadのみ)
・別のView Controllerからモーダルモードで表示する。
・Popoverから表示する。(iPadのみ)

モーダルモードでのTab Bar Controllerの表示
(一般的ではありませんが)アプリケーションでTab Bar Controllerをモーダルモードで表示すること もできます。Tab Barインターフェイスは、通常はアプリケーションのメインウインドウにインストー ルされ、必要な場合にだけ更新されます。ただし、インターフェイスの設計において必要と認められ る場合には、Tab Bar Controllerをモーダルモードで表示することも可能です。たとえば、アプリケー ションの主たる操作モードを、Tab Barインターフェイスを使用したまったく別のモードに切り替える には、クロスフェードトランジションを使用して、第2のTab Bar Controllerをモーダルモードで表示します。
Tab Bar Controllerをモーダルモードで表示する場合は、必ずpresentModalViewController:animated: メソッドの第1パラメータにTab Bar Contrllerオブジェクトを渡します。このTab Bar Controllerは、表示する前にすでに設定されていなければなりません。したがって、Tab Barインターフェイスをメインウ インドウにインストールする場合とまったく同じ方法で、ルートView Controllerを作成して設定し、それらをTab Bar Controllerに追加する必要があります。

ということらしいので、

・TabBarControllerの定義は、AppDelegateで行う。
・表示は、別のView Controllerからモーダルモードで行う。

ということでいいようです。

【参考】
Tab Bar Controllers
Combined View Controller Interfaces
iOS View Controller カタログ(PDF/上記2つの日本語訳)
iOS View Controller プログラミングガイド(PDF)
StoryboardとSegueの基本 – Kesin’s diary
画面間でのデータの受け渡しに付いて: 永遠ログ
iOS – segue による画面遷移メモ – Qiita
日本語ドキュメント – Apple Developer
プログラム側からUITabBarControllerを切り替えて、さらに画面遷移させたい時 – makoラボ
Programming.log, [Objective-C] applicationDidFinishLaunching とは

【Xcode】UIBezierPathをアニメーションで描画

【Xcode6.2 + iOS 8.4(iPhone5) + MacOX10.9.5】

UIBezierPathはベジェ曲線を描画するクラスですが、この描画そのものをアニメーションさせられないかと調べてみました。

まずはUIBezierPathの使い方、この辺が参考になります。
[iPhone] UIBezierPath 図形の描画 (Objective-C)
[Swift] UIBezierPathを使って、直線、楕円、矩形などで描画する
UIBezierPathで曲線を描画してみた | 丸ノ内テックブログ
UIBezierPathで図形を描画する。: iPhoneソースコードがきたなくて

で、実際に書いてみたのがこちら。

iOS Simulator Screen Shot 2015.10.05 3.03.25
UIBezierPathでローディング的な円を描いてみた。

コードはこんな感じ。

・CircleView.h

//
//  CircleView.h
//  testUIBezierPath
//
//  Created by c-geru on 2015/10/04.
//  Copyright (c) 2015年 c-geru. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface CircleView : UIView

@end

・CircleView.m

//
//  CircleView.m
//  testUIBezierPath
//
//  Created by c-geru on 2015/10/04.
//  Copyright (c) 2015年 c-geru. All rights reserved.
//

#import "CircleView.h"

@implementation CircleView

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // 円弧 -------------------------------------
    UIBezierPath* arc
    = [UIBezierPath bezierPathWithArcCenter:
       CGPointMake(self.frame.size.width/2,self.frame.size.height/2) radius:125.0f startAngle:M_PI/2*-1 endAngle:M_PI*2 clockwise:YES];
    UIColor *aColor = [UIColor lightGrayColor];
    [aColor setStroke];
    arc.lineWidth = 10;
    // 点線のパターンをセット
    CGFloat dashPattern[2] = { 2.0f, 4.0f };
    [arc setLineDash:dashPattern  count:2 phase:0];
    [arc stroke];

    // 円弧 (アニメーション)-------------------------------------
    UIBezierPath* arc2
    = [UIBezierPath bezierPathWithArcCenter:
       CGPointMake(self.frame.size.width/2,self.frame.size.height/2) radius:125.0f startAngle:M_PI/2*-1 endAngle:M_PI*4/4 clockwise:YES];

    UIColor *aColor2 = [UIColor blueColor];
    [aColor2 setStroke];

    arc2.lineWidth = 10;
    // 点線のパターンをセット
    CGFloat dashPattern2[2] = { 2.0f, 4.0f };
    [arc2 setLineDash:dashPattern2  count:2 phase:0];
    [arc2 stroke];
}
@end

で、この青い部分をローディングバー的にアニメーションしたかったわけです。

基本的にアニメーションはCALayerってことはわかったんだけど、アニメーションさせるためのパラメタの渡し方がよくわかりませんでした。

iPhone – パスに沿ってアニメーションさせる – Qiita
CALayerを使ってアニメーションしよう – make.appアプリ開発Tips

更に調べてみると、描画要素(fillColor,strokeColor,lineWidth,lineDashPattern)をUIBezierPathでなく、CALayer側に渡してあげればいいみたい。アニメーションで描画するので、考えてみれば当然か。

iOS Development Tricks: Custom Circular Progress View for iOS
CAShapeLayer example – Round corners view with dashed line border | Luka Gabric

最終的にアニメーションできたコードがコレ。

・CircleView.h

//
//  CircleView.h
//  testUIBezierPath
//
//  Created by c-geru on 2015/10/04.
//  Copyright (c) 2015年 c-geru. All rights reserved.
//

#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>

@interface CircleView : UIView

@end

・CircleView.m

//
//  CircleView.m
//  testUIBezierPath
//
//  Created by c-geru on 2015/10/04.
//  Copyright (c) 2015年 c-geru. All rights reserved.
//

#import "CircleView.h"

@implementation CircleView

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // 円弧 -------------------------------------
    UIBezierPath* arc
    = [UIBezierPath bezierPathWithArcCenter:
       CGPointMake(self.frame.size.width/2,self.frame.size.height/2) radius:125.0f startAngle:M_PI/2*-1 endAngle:M_PI*2 clockwise:YES];
    UIColor *aColor = [UIColor lightGrayColor];
    [aColor setStroke];
    arc.lineWidth = 10;
    // 点線のパターンをセット
    CGFloat dashPattern[2] = { 2.0f, 4.0f };
    [arc setLineDash:dashPattern  count:2 phase:0];
    [arc stroke];

    // 円弧 (アニメーション)-------------------------------------
    UIBezierPath* arc2
    = [UIBezierPath bezierPathWithArcCenter:
       CGPointMake(self.frame.size.width/2,self.frame.size.height/2) radius:125.0f startAngle:M_PI/2*-1 endAngle:M_PI*4/4 clockwise:YES];

    if (self.pathLayer == nil)
    {
        CAShapeLayer *shapeLayer = [CAShapeLayer layer];

        shapeLayer.path = [arc2 CGPath];

        shapeLayer.fillColor = [UIColor clearColor].CGColor;
        shapeLayer.strokeColor = [UIColor blueColor].CGColor;
        shapeLayer.lineWidth = 10;

        shapeLayer.lineDashPattern = [NSArray arrayWithObjects:[NSNumber numberWithInt:2], [NSNumber numberWithInt:4], nil];

        [self.layer addSublayer:shapeLayer];
        self.pathLayer = shapeLayer;
    }

    CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    pathAnimation.duration = 3.0;
    pathAnimation.fromValue = [NSNumber numberWithFloat:0.0];
    pathAnimation.toValue = [NSNumber numberWithFloat:1.0];
    [self.pathLayer addAnimation:pathAnimation forKey:@"drawCircleAnimation"];
}
@end

【jQuery】jQueryRotate.jsがIE8で動かなかった件(解決)

某ページで画像を回転させる必要があって、見つけたのがコレ。

jQueryRotate – rotate image in browser by any angle

【参考】
いろんな画像をクルックルクルックル回すイケイケjQueryプラグイン 「jQueryRotate」 | うずまきブログ
アナログ時計をJavaScriptで作ってみた

IE6以降対応ってことで楽勝だと思っていたら、IE8で動かなかった。。。厳密には1回だけ回ってくれるけど、それ以降はまったく無反応。具体的にはこんな関数をクリックイベントに割り当ててました。

【JavaScript】

var rotateImg = 0;

//画像回転処理(右)
function clickTiltRightFunc(){
	rotateImg += 90;
	rotateImg = (rotateImg >= 360) ? 360 - rotateImg : rotateImg;
	
	$("#thumbImg img").rotate(rotateImg);
	$('input[name="rotateImg"]').val(rotateImg);
}

【html】

<div class="photo" id="thumbImg">
 <img src="xxxx.jpg">
</div>

公式サイトを改めてIE8で見たら「動いてないじゃん!」となったんだけど、「公式サイトのjQueryが2.xだから」と某所から指摘を受けて納得。

【参考】
jQuery 2.0がついに正式リリース。IE8以前はサポートせず、より軽量で高速に - Publickey
jQueryのバージョン1.xと2.xの違いは対応ブラウザ。Win XPつまりIE8以下・6以上のサポートが必要なら1系を使い,モダン・スマホサイトは2系を使う – プログラミングとIT技術をコツコツ勉強するブログ

で、いろいろ試してみて気づきました。IE8ではimgタグを直接指定しないとダメらしい。つまり $(“#thumbImg img”) のようなサイン省参照ではなく、直接imgタグにidをつけてそのidに対してrotateするということです。

改定版がこちら。

【JavaScript】

var rotateImg = 0;

//画像回転処理(右)
function clickTiltRightFunc(){
	rotateImg += 90;
	rotateImg = (rotateImg >= 360) ? 360 - rotateImg : rotateImg;
	
	$("#thumbImg").rotate(rotateImg);
	$('input[name="rotateImg"]').val(rotateImg);
}

【html】

<div class="photo">
 <img src="xxxx.jpg" id="thumbImg">
</div>

たったコレだけなんですけど、意外とハマったのでメモしておきます。

【Xcode】Facebook投稿でplugin com.apple.share.Facebook.post invalidated

【Xcode6.2 + iOS 8.4(iPhone5) + MacOX10.9.5】

引き続きFacebook投稿の話です。

前回のポストに書いたようにFacebook投稿自体は出来るようになったのですが、プログラムで設定したメッセージが表示されませんでした。コードはこんな感じ。

//facebook:送信
- (IBAction)sendFB:(UIBarButtonItem *)sender {

    // 組み込みのFacebookが利用可能な端末かを検証する
    if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook]) {
        
        // Facebook投稿機能のインスタンスを作成する
        SLComposeViewController *slComposeViewController = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
        
        
        // 投稿するコンテンツを設定する
        // 表示する文字列
        [slComposeViewController setInitialText:@"#アイコン顔カメラ"];
        // URL
        [slComposeViewController addURL:[NSURL URLWithString:@"http://www.c-geru.com/"]];
        // 画像
        [slComposeViewController addImage:[UIImage imageNamed:@"icon_10.png"]];
        
        // 処理終了後に呼び出されるコールバックを指定する
        [slComposeViewController setCompletionHandler:^(SLComposeViewControllerResult result) {
            
            switch (result) {
                case SLComposeViewControllerResultDone:
                    NSLog(@"Done!!");
                    break;
                case SLComposeViewControllerResultCancelled:
                    NSLog(@"Cancel!!");
            }
        }];  
        
        // 表示する
        [self presentViewController:slComposeViewController animated:YES completion:nil];    
    }

}

で、表示される画面がコレ。「slComposeViewController setInitialText:」のテキストが表示されていません。
メッセージが表示されない

この画面でテキスト入力すると、そのテキストは投稿されますが、Xcodeに下記のようなメッセージが表示されます。

plugin com.apple.share.Facebook.post invalidated

【追記】2015.8.17 ちなみに「slComposeViewController setInitialText:」をコメントにしても、投稿後に上記メッセージが表示されます。

調べてみると、こんな情報が。

ios – UIActivityViewControllerでFacebookにシェアできない – スタック・オーバーフロー
sharing – ios plugin com.apple.share.Facebook.post do not show provided text – Stack Overflow

これによると、Facebook側のポリシー変更ということのようです。

Platform Policy 2.3 Example and Explanation

メッセージは基本ユーザに入力してもらうと考えれば、ハッシュタグつけるとか以外に困ることはなさそうですが、一応備忘録として。

【Xcode】Facebook投稿で「ログインしていません」と表示される

【Xcode6.2 + iOS 8.4(iPhone5) + MacOX10.9.5】

アプリからFacebook/twitterへの投稿は、投稿するだけなら各サービスへのアプリ登録は必要なく、Social.FrameworkをインポートしてSLComposeViewControllerを使えばカンタンに出来るらしい。

Objective-C – LINE/Facebook/Twitter投稿 – Qiita
[XCODE] iOS組み込みのFacebook投稿機能を使う方法 – YoheiM .NET
【Xcode】Facebook、TwitterにiOS標準フォームで投稿する
serviceType – SLComposeViewController Class Reference

で、試してみたところ、Facebookの方は「ログインしていません」とメッセージが出て投稿できない。

ログインしていません
表示されるアラート

iPhone側では・・・

・Facebookアプリはインストール、ログイン済。
・iPhoneの 設定>Facebook でID、パスワードは登録済み。

になっています。

いろいろテストしてみたところ、下記の手順で投稿できるようになりました。

1.Facebookアプリをログアウト。
2.iPhoneの 設定>Facebook でID、パスワードの登録を確認。
3.Facebookアプリでログイン。

Facebookアプリに最初にログインしたときに、iPhoneの 設定>Facebook でID、パスワードを登録せずに、Facebookアプリ側でログインしていたため、Xcode側からは設定情報を使ってログインされていないと判断されていたみたいです。

またFacebookアプリはログイン状態を保持しているので、iPhone上でFacebookアプリが起動されているかどうかではなく、Facebookアプリログインされた状態になっているかどうかで判断しているようです。

ブラウザ上でのFacebookページへのログイン状態は関係しないようです。まあ設定の情報を使っていないので、当たり前か。

【Objective-C】BSXPCMessage received error for message: Connection interrupted というエラーメッセージ

【Xcode6.2 + iOS 8.4(iPhone5) + MacOX10.9.5】

Xcode5でiOS7をターゲットにして作ったアプリの改修をしていて、Xcode6.2でiPhone5の実機にビルドすると「BSXPCMessage received error for message: Connection interrupted」というメッセージが出てきます。

※同じ環境で、iPhone4S(iOS 7.1.2)では発生せず。

起動時のみログにメッセージが表示されるだけで、動作そのものには影響なさそうだけど、気になるので調べてみました。

【参考】ios – BSXPCMessage received error for message: Connection interrupted – Stack Overflow

このサイトを見てみると、どうやら「iOS 8でCIFilterのバグが原因」ということらしい。

CIContextのcontextWithOptionsで指定するoptionに、iOS8以降で項目(kCIContextPriorityRequestLow, kCIContextWorkingFormat)が追加されているので、明示的にオプションを指定しないとダメということなのかな?

【参考】+ contextWithOptions: – CIContext Class Reference
【参考】Context Options – CIContext Class Reference

とりあえずこのアプリはiOS7以上になっているので、「kCIContextUseSoftwareRenderer」を指定することでエラーは消えました。

【修正前】

_imageContext = [CIContext contextWithOptions:nil];

【修正後】

NSDictionary *contextOptions = [NSDictionary dictionaryWithObjectsAndKeys:
                                    [NSNumber numberWithBool:YES],kCIContextUseSoftwareRenderer,nil];
_imageContext = [CIContext contextWithOptions:contextOptions];

※ imageContextはCIContextとして定義されています。

@property (nonatomic, strong) CIContext *imageContext;

その他、下記のサイトを参考にしました。感謝。

超できるかな(Swiftでカメラアプリ1)
Study Swift: CIFilter – Invert the photo color by built-in filter
CoreImageで画像の加工をする その3「GPUにするべきかCPUにするべきか」 – Teratoma

手持ちの環境が対応してないので確認出来ないんだけど、Xcode6.3では直っているのかしらん?

【Xcode】Audio Uint関連リンク

あるアイデアが浮かんだので、Audio Uint関連を調べてみたけど、現状まだよくわかりません。。。

リンクばかり増えてSafariがタブだらけなので、まとめておきます。

・Objective-C – iOSで特定の周波数の音を鳴らす方法 – Qiita
これはやってみた。iOS8からは一部変更されているようで、warningが全ては消えないものの、とりあえずXcode6.2で動作しました。変更点はここ(CoreAudio Changes/iOS Developer Library — Prerelease)にあるけど、イマイチ理解できず。

よさそうなのが、今や入手困難な「iPhone Core Audioプログラミング」の著者が書いたブログ。書籍のベースになった記事らしい。この順に読むのがいいらしい。途中まで読んだ。

・Getting Started With Audio Unit
・Introduction to Audio Unit Development
・iPhone Core Audio

本家Appleのドキュメント

・Audio Unit Hosting Guide for iOS

あとコレ。第10〜15回までAudio関連の話。

・実践! iPhoneアプリ開発 (10) 楽器アプリの作り方 (1) – iPhoneのオーディオフレームワーク | マイナビニュース

Core Audio関係はこの辺り。後で必要になるかもしれないので。ただ一般的な話とか、オーディオファイル再生みたいな話は、前にMusicPlayerを試作したときにある程度調査済。

・iOS CoreAudioを使う上で参考になったサイト – 日々の記録。
・iOS Core Audio | シリーズ |Developers.IO
・Core Audioの概要(PDF)
・Core Audioの復習 | Second Flush

iOSには直接関係しないけど、Web Audio API関連。

・Web Audio API を使用してウェブブラウザをギターのチューナーにする件. | hirooka.pro
・Web Audio API の Oscillator で楽器を作りたい話 – Mach3.laBlog

これも直接関係ないけど、周波数の話として。
・ギターの音程とフレット/ELECTRIC GUITAR & BASS SUPER MANUAL

今のところ、見つかったのはこんなところで。やっぱり資料的にはObjective-Cの方が潤沢。特にあまり情報のないものは。

【2015.8.3 追加】
・Audio Unit 再入門 – Over&Out その後

Twitterで特定期間のツイートを検索する

先日、Twitterについて調べていたときに、こんな記事を見つけました。

・Twitterで期間を限定して検索する方法&ヘルプに載ってない裏技テク – 聴く耳を持たない(片方しか)
・Twitterの新機能! 過去のツイートを検索する方法 | iPhoneひとすじ! かみあぷ速報

試してみると、コレ、公式サイトの検索窓を使わずにブラウザで直接URL叩いても動くんですね。Twitterにログインしてなくても表示されます。例えば、こんな感じ

で、フォローしている鍵アカも検索できるように、twitterアカウントでOAuth認証を通すようにして、ひとネタページを作ってみました(下の画像からリンクしてます)。

thum_fb_2tones
【twitter】○○年の今頃何してた? | 2tones-dev.net

やってることは基本的に、入力したアカウントと選択した年と現在の日付から前後一日を取得して、JavascriptでURL生成してwindow.open()してるだけです(笑)。あとアカウントのデフォルトは、OAuth認証で返ってくる情報から自分のアカウントを自動入力しています。

まあ検索するなら公式サイトの検索窓使うかURL直打ちすればいいんですが、いちいちキーワード入力するのも面倒だし(ライトユーザーはそんなことしなさそうだし)、ふと「去年の今頃何してたっけ?」みたいなことを思ったりすることもたまにあるので、ネタとしてはいいかなと思いまして(笑)。

ちなみに検索に前後一日ずつの幅を持たせているのは、なるべく検索にヒットするようにです。みんながみんな、毎日ツイートしてるわけじゃないと思うので。

APIでも過去検索できればアプリに組み込んだりできるんですが、そこはまあ負荷の問題なんですかね。制限があるのは。

ちなみにOAuth認証はこの辺を参考にPHPで書いています。

・【PHP】2015春版!TwitterOAuthでログイン機能を実装する – Qiita
・PHP と Twitter API V1.1 で OAuth 認証を行う 「タイムライン取得」「呟き(つぶやき)投稿」「ログイン」(API V 1.1)

twitterでリンクにサムネイル設定するには「Twitter Cards」というのを使うんですね。この辺も普段あまり自分で書かないのでしりませんでした。

・すぐにできるTwitter Cards設定 – E-riverstyle Vanguard

FacebookのOPG用画像をチェックするのに、こんなサイトがありました。フルサイズでも小さい表示でもうまく表示されるよう確認するのに便利です。

・OGP画像シミュレータ | og:image Simulator

Twitterに限らずAPI周りの情報はたくさんありますが、古いAPIの情報だったり、Developersページのデザインが変わってたりするので、その辺が注意点かと。

【補足】
・当初iPhoneのSafariでURLを叩いてみたら、Safariで未ログインだと検索結果が表示されませんでした。iPhoneだとモバイル用のページが開くので、その辺の仕様に違いがあるのかなと。また最初は別ウィンドウで表示するようにしていたのですが、iPhoneだと別タブで公式サイトを開いていると、そちらに結果が表示されてしまいました。

・上記の現象があったのでtwitterのOAuth認証を組み込んだのですが、このブログ書くために再度テストしたら未ログインでも結果表示されていました。キャッシュの問題なのか、再現しないのでちょっとわからないですが。。。

フリーランスのための入院心得(収支編)

前回、入院についてのあれこれを書きましたが、入院関連の全ての請求、保険の申請・入金があり、収支が出たのでまとめておきます。実際にはこの点が一番の興味ではないかと思うので。

1.前提

・保険は国民健康保険。
限度額適用認定証を申請・取得済
・生命保険は都民共済(総合保障4型医療特約

2.支出(医療費)

期間 総医療費(保険) 患者負担額(保険) 総医療費(保険/食事) 患者負担額(保険/食事) 患者負担額合計 備考
4/22-4/30 419,670円 81,627円 16,868円 5.980円 87,607円 4/23手術
5/1-5/16 440,440円 81,834円 33,736円 11,960円 93,794円 5/8再手術

合計での費用は、181,401円

国民健康保険で30%負担なので、限度額適用認定証がなかった場合は258,033円になります。もちろん後から返金されるわけですが、一時的な支払差額は+76,632円になります。

ちなみにウチの場合、限度額適用認定証の所得区分は「一般所得世帯(B)」に分類されました。詳しくはこちら

3.支出(入院セット【寝間着+フェイスタオル+バスタオル】のレンタル)

期間 単価 数量 金額 消費税 合計 備考
4/22-4/30 350円 9日 3,150円 250円 3,402円
5/1-5/16 350円 15日 5,250円 420円 5,670円 退院日分は請求なしという契約で、請求は15日分

合計での費用は、9,072円

4.収入(都民共済からの共済金)

内訳 金額 備考
総合保障型入院共済金25日 225,000円 総合保障4型(9,000円×25日)
医療特約入院一時金 20,000円 医療特約
医療特約在宅療養共済金 40,000円 医療特約(20日以上の入院で支払われる一時金)
医療特約手術共済金 50,000円 医療特約
共済金合計 335,000円 総合保障4型+医療特約で支払われる合計額

5.収支

内訳 金額 備考
支出(医療費) -181,401円
支出(入院セット) -9,072円
収入(都民共済からの共済金) +335,000円
収支 +14,4527円

実際には入院に際して事前検査(MRI、心電図、呼吸器検査、X線等)で17,000円弱、入院期間中の冷蔵庫使用料(24h200円×25日=5,000円)、共済金申請のための病院での「手術・放射線照射診療報酬点数確認書」の発行依頼(2.160円)、飲み物など必要なモノを買ってきてもらったりでいくらか出費がありますが、それでも共済金で賄えました。

ちなみに共済金申請の書類を送付(普通郵便でポストに投函)してから、共済金が振り込まれるまで3日でした。共済すげえ(笑)。

まだ若干通院が残っていますが、順調に回復しているので、当面病院のお世話にならないように気をつけたいものです。この記事がいざという時のための参考になれば幸いです。

AS,Objective-C,Javascript,その他諸々の備忘録