6/28/2010

AVFoundation.framework might be included in Mac OS 10.7

AVFoundation.framework in iOS4 has AVBase.h file as follow

/*
File:  AVBase.h

Framework:  AVFoundation

Copyright 2010 Apple Inc. All rights reserved.

 */

#import

// Pre-10.7, weak import
#ifndef __AVAILABILITY_INTERNAL__MAC_10_7
#define __AVAILABILITY_INTERNAL__MAC_10_7 __AVAILABILITY_INTERNAL_WEAK_IMPORT
#endif

Apple makes efforts to the maintenance of API related to the sound caused by AVFoundation, and I think this is a strongly possibility.


iOS4 の AVFoundation.framework あたりを見ていたら 10.7 に AVFoundation が搭載されることを示唆する記述を発見。AVBase.h 以外のところにも記述はある。AVFoundation は iPhoneOS 上でサウンド関係の API として整備されてきており、これが現実になる可能性は高いだろう。

5/15/2010

CALayer setting in initWithFrame:

I try to make custom view that is high performance and animatable. I set layer in custom view's initialize method initWithFrame:

- (id)initWithFrame:(NSRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
  CALayer *layer = [CALayer layer];
  CGColorRef color = CGColorCreateGenericGray(0.0, 1.0);
  layer.backgroundColor = color;
  CGColorRelease(color);
  [self setLayer:layer];
  [self setWantsLayer:YES];
  }
    return self;
}

but, layer doesn't see why.
In some CALayer's sample codes, layer setting is done in awakeFromNib.

- (void)awakeFromNib {
    NSLog(@"%d", [self wantsLayer]);
    NSLog(@"%@", [[self layer] description]);
}

I check as above, layer is exist but wantsLayer method return NO.
Layer now appears that properly implemented as follows.

- (void)awakeFromNib {
    [self setWantsLayer:YES];
}

When custom view is made from code, not nib, awakeFromNib method doesn't call but setWantsLayer: work properly. I looked for document about timing of setWantsLayer: to NSView but could not find. Anyone know?


CALayer を使って高速かつアニメーション可能なカスタムビューを作ろうと思って、カスタムビューの初期化メソッド initWithFrame: でレイヤーを設定してみた。

- (id)initWithFrame:(NSRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
  CALayer *layer = [CALayer layer];
  CGColorRef color = CGColorCreateGenericGray(0.01.0);
  layer.backgroundColor = color;
  CGColorRelease(color);
  [self setLayer:layer];
  [self setWantsLayer:YES];
  }
    return self;
}

でもこれだとなぜかレイヤーが表示されない。
CALayer のサンプルコードを見るとレイヤーの設定は awakeFromNib 内で行われていた。

- (void)awakeFromNib {
    NSLog(@"%d", [self wantsLayer]);
    NSLog(@"%@", [[self layerdescription]);
}

として確認してみると、レイヤーは設定されているが wantsLayer が NO を返しているようだ。
以下のように実装することでちゃんとレイヤーが表示されるようになった。

- (void)awakeFromNib {
    [self setWantsLayer:YES];
}

カスタムビューが nib でなくてコードから生成される場合には awakeFromNib は呼ばれないが setWantsLayer: は正しく効く。この NSView への setWantsLayer: のタイミングについてドキュメントを探しけど見つけられなかった。正しい解答が得られないまま使うのは気持ち悪いけどとりあえず。

3/09/2010

Automate to delete private header of own framework

When you build application using own framework, class header file does exist in package.
It's no matter for public framework, but off course we don't want to open class header rerated to activation or authorization.
After build application, you need delete

MyApp.app/Contents/Frameworks/MyKit.framework/PrivateHeaders
or
MyApp.app/Contents/Frameworks/MyKit.framework/Versions/A/PrivateHeaders

It's troublesome.
In Xcode, select your target and
Project > New Build Phase > New Run Script Build Phase
or control click target and select
Add > New Build Phase > New Run Script Build Phase
from context.
Write script like follow and you can perfectly automate this work

cd "${TARGET_BUILD_DIR}/${FULL_PRODUCT_NAME}/Contents/Frameworks"
rm -rf *.framework/PrivateHeaders
rm -rf *.framework/Versions/*/PrivateHeaders

It saves much time.


自作フレームワークを組み込んだアプリケーションをビルドする時、パッケージの中にヘッダファイルが残ってしまう。
公開したいフレームワークの場合はいいんだけど、アクティベートとかオーソライズといったものに関連したフレームワークのヘッダなんてもちろん公開したくない。
アプリケーションをビルドしたあと、ビルドされたアプリ内の

MyApp.app/Contents/Frameworks/MyKit.framework/PrivateHeaders

MyApp.app/Contents/Frameworks/MyKit.framework/Versions/A/PrivateHeaders

あたりのファイルを削除する必要があるけど、アプリケーションのビルドの都度これらを Finder 上で削除するのは非常に面倒。
Xcode のメニューで
プロジェクト > 新規ビルドフェーズ > 新規スクリプトを実行
もしくはターゲットを右クリックしてコンテクストメニューから
追加 > 新規ビルドフェーズ > 新規スクリプトを実行
を選択し以下のようなスクリプトを入力することでこの作業を完全自動化できる。

cd "${TARGET_BUILD_DIR}/${FULL_PRODUCT_NAME}/Contents/Frameworks"
rm -rf *.framework/PrivateHeaders
rm -rf *.framework/Versions/*/PrivateHeaders

めちゃくちゃ時間の節約になる。

3/04/2010

UIImagePickerController doesn't work in certain cases

The following are the codes that use UIImagePickerController with UIImagePickerControllerSourceTypeCamera.
This code is written in subclass of UIViewController and "self" is UIViewController.

if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
  UIImagePickerController *controller = [[UIImagePickerController alloc] init];
  controller.sourceType = UIImagePickerControllerSourceTypeCamera;
  [self presentModalViewController:controller animated:NO];
  [controller release];
}

This code doesn't work at -viewDidLoad and -viewWillAppear:
At -viewDidAppear:, that works properly.

For example, in AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  //insert initialize code here, not work
  [window addSubview:viewController.view];
  [window makeKeyAndVisible];
  //insert initialize code here, work

  return YES;
}

初期化した UIImagePickerController を View がオフスクリーン状態の ViewController を利用して表示しようとすると正しく動作しない。UIImagePickerControllerSourceTypePhotoLibrary でも試してみたけど同じく動作しない。View がオンスクリーンになっている ViewController を利用して表示しないといけないみたい。

spec iPhone 3GS OS 3.1.3

2/20/2010

QTMovieView delegate hidden method

QTMovieView has delegate that follows

- (CIImage *)view:(QTMovieView *)view willDisplayImage:(CIImage *)image;

This delegate method is not listed in current newly SDK's document.
But it's defined in QTMovieView.h in QTKit.framework.
It works properly.
On default, this method has name conflict with QTCaptureView delegate

- (CIImage *)view:(QTCaptureView *)view willDisplayImage:(CIImage *)image;

Xcode will show warning about conflict.
You can implement QTMovieView delegate method as follow

- (CIImage *)view:(id)view willDisplayImage:(CIImage *)image {

if ([view isKindOfClass:[QTMovieView class]]) {
  //your code
  return image;
  }

return image;
}

QTMovieView にはドキュメントに載ってないけど header に定義されてる delegateメソッドがある。
ただ QTMovieCaptureView の delegateメソッド名と被っているので、Xcode でビルドすると警告が出る。クラス名の部分を id なんかにしてやって、メソッド内でメソッドの送り主が意図するクラスかどうかをチェックして必要に応じて処理するといいんじゃないかという話。

spec OS 10.6.2, Xcode 3.2.1, 3.2.2

2/14/2010

Quartz Composer movie export


Quartz Composer で File > Export as QuickTime Movie...
QuickTime 書き出しする際にムービーの分数秒数の指定ができるけど、ここで指定した値が正しく反映されない。確か以前は正しく反映されていたはず。いつからこの問題が起きたのかは分からないけどとりあえず OS v10.6.2, Quartz Composer v4.0 では正しく機能しないよう。
Terminal で

defaults write NSGlobalDomain QuartzComposerDefaultMovieDuration 90

としてデフォルトの書き出し秒数を指定してやることでムービーの秒数を指定してやることができる。ということは Quartz Composer が書き出し時の秒数オプションを無視してデフォルト設定を使用してしまっているということになる。
ムービーの書き出し時間を変更したいその都度ターミナルでこのコマンドを打てばいいんだけど、、まぁそりゃないな。


On Quartz Composer, File > Export as QuickTime Movie...
It's possible to specify movie duration, but exported movie that include Quartz Composer Track doesn't have specified duration.
on Terminal

defaults write NSGlobalDomain QuartzComposerDefaultMovieDuration 90

this command can specify exported movie's duration.
But why function that specifies duration is not working properly?
It's strange that Quartz Composer use default duration always.

spec OS 10.6.2, Quartz Composer 4.0

about this blog

・このブログについて
日々プログラムをしていて気付いたことや疑問に思ったことをメモしていきます。
・目標
Tips, bugはなるべく英語で書く。

-about this blog
I take notes of awareness and doubt in programming.
-aim
Write Tips and bug in English as possible. (Sorry, I'm not good at English.)