2010-07-25
■[iPhone] TweetなうのソースコードがSDK4.0でビルド出来ない問題に対処しました

GitHubに公開しているTweetなうのソースコードがSDK4.0でビルド出来なくなっていましたので対処しました。
Xcode3.2.3でベースSDKを4.0にしてビルドすると以下のようなエラーが発生します。
Undefined symbols:
"_OBJC_CLASS_$_OAConsumer", referenced from:
objc-class-ref-to-OAConsumer in XAuthTwitterEngine.o
"_OBJC_CLASS_$_OARequestParameter", referenced from:
objc-class-ref-to-OARequestParameter in ExchangeCredentialsOperation.o
"_OBJC_CLASS_$_OAToken", referenced from:
objc-class-ref-to-OAToken in XAuthTwitterEngine.o
"_OBJC_CLASS_$_OAMutableURLRequest", referenced from:
objc-class-ref-to-OAMutableURLRequest in ExchangeCredentialsOperation.o
objc-class-ref-to-OAMutableURLRequest in XAuthTwitterEngine.o
"_OBJC_CLASS_$_OADataFetcher", referenced from:
objc-class-ref-to-OADataFetcher in ExchangeCredentialsOperation.o
XAuthTwitterEngineが使っているMGTwitterEngine のバージョンを上げたところ解決できました。調べてみるとMGTwitterEngineで変わったところは MGTwitterXMLParser.h と libOAuth.a のみでした。たぶん libOAuth.a に問題があるのだと思います。
そこで、 libOAuth.a の未定義になっているシンボルを nm で調べてみると
古いもの
00000000 A .objc_class_name_OAConsumer
U _OBJC_CLASS_$_NSObject
000015f8 D _OBJC_CLASS_$_OAConsumer
000015f0 D _OBJC_IVAR_$_OAConsumer.key
000015f4 D _OBJC_IVAR_$_OAConsumer.secret
U _OBJC_METACLASS_$_NSObject
最新のもの
00000000 A .objc_class_name_OAConsumer
U _OBJC_CLASS_$_NSObject
00001364 S _OBJC_CLASS_$_OAConsumer
00001464 S _OBJC_IVAR_$_OAConsumer.key
00001460 S _OBJC_IVAR_$_OAConsumer.secret
U _OBJC_METACLASS_$_NSObject
未定義に成ってしまったシンボルのClassが D(データセクション) から S(bbs) に変わっています。bbsは初期化してない(プログラム起動時に0に初期化される)広域変数の入るセクションですので、データセクションみたいなものだと思うのですが、なぜ未定義になってしまうのでしょうか?
2010-07-19
■[iPhone] ObjectiveResource が iOS4.0 で動かなくなった (ObjectiveResourceはだいじょうぶ?)

以前作って、お客様に納めてしまったiPhoneデモアプリが SDK4.0で実機にインストール出来ないという連絡をもらい調査したところ実機にインストール出来ないのはプロジェクト設定の問題でしたが、iOS4にインストールすると落ちます ^^;
調べてみると、ObjectiveResourceの中でスタックオーバーフローで落ちています。ObjectiveResourceを調べてみると NSObject を継承したModel(DTO)のインスタンスをシリアライズ(XML化)する中でスタックオーバーフローしています。
Model(DTO)にはRailsのModelに対応するインスタンス変数しか定義されていないのに、accessibilityValue とかいうインスタンスをシリアライズしようとして再帰呼び出しが止まらなくなっていました。
結局 ObjectiveResource の MLに Recursion in OS 4.0 というスレがあり解決策も書かれていました。
原因は iOS4.0になって NSObjectに accessibilityLanguage, accessibilityFrame, accessibilityTraits, accessibilityHint, accessibilityValue, accessibilityLabel,isAccessibilityElementなどのインスタンス変数が追加されていて、これらをシリアライズする際に無限再帰に入ってしまうようです ^^);
それはそれとして、最近の ObjectiveResourceの開発は上の画像のようにオリジナルの開発者は開発をコントロールしてないようで、たくさんの人が fork を作って、それぞれ開発を進めているようです !! だいじょうぶなのかなぁ〜?
2010-07-14
■[教育] 最近おこなったEY-Officeらしい教育の実例に付いて書きました。

会社ホームページのblogに最近おこなった教育から を書きました。
社内で充分な教育は行えないが、既存の教育の効果には不安を感じておられる開発マネージャーの方、採用担当の方、是非ご覧下さい。
■[iPhone] ツールバーのボタンを実行時に切り替える際の注意

現在作成中のアプリでは、下のようにツールバーに乗っているボタン等を実行時に切り替える必要があります。
- toolbar1
・・・ ↑ ・・・切り替え・・・ ↓ ・・・
- toolbar2
ツールバー上のアイテム(UIBarButtonItem) はsetToolbarItemsを使って、配列でツールバーに設定できます。
そこで、以下のように toolbar1, toolbar2の配列を作って実行時に、setToolbarItems: に toolbar1、またはtoolbar2を設定する事で切り替えるようにしたところ、なぜか右端のスライダーが表示されません !!
pageSlider = [[UISlider alloc] initWithFrame:CGRectMake(0,0,200,30)]; .... soundSegment = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:@"●●●●", @"○○○○", nil]]; .... self.toolbar1 = [[NSArray alloc] initWithObjects: BarImageFileButtonItem(@"play_icon.png", @selector(repeatSound)), [[[UIBarButtonItem alloc] initWithCustomView:soundSegment] autorelease], BarFlexibleSpaceButtonItem, [[UIBarButtonItem alloc] initWithCustomView:pageSlider], nil]; self.toolbar2 = [[NSArray alloc] initWithObjects: BarFlexibleSpaceButtonItem, [[UIBarButtonItem alloc] initWithCustomView:pageSlider], nil];
いろいろと試してみたのですが、夜中になって解りました! スライダーは1つのオブジェクト(インスタンス)を使っていますが、それを乗せているUIBarButtonItemが同じオブジェクトでないのが原因でした ^^);
pageSlider = [[UISlider alloc] initWithFrame:CGRectMake(0,0,200,30)]; .... soundSegment = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:@"●●●●", @"○○○○", nil]]; .... self.toolbar1 = [[NSArray alloc] initWithObjects: BarImageFileButtonItem(@"play_icon.png", @selector(repeatSound)), [[[UIBarButtonItem alloc] initWithCustomView:soundSegment] autorelease], BarFlexibleSpaceButtonItem, [[UIBarButtonItem alloc] initWithCustomView:pageSlider], nil]; self.toolbar2 = [[NSArray alloc] initWithObjects: [toolbar1 objectAtIndex:2], [toolbar1 objectAtIndex:3], nil];
このように変更したところ動きました。
■[iPhone] UIWebViewでタッチイベントを取得するには

HTMLを表示出来るUIWebView は便利でビューですが、そのままでは、指でタッチしたりピンチしたイベントがとれません。そこでいろいろと試してみた事を書いてみます。
UIWebViewをハック
書籍やネットを探し UIWebView の touch イベントをフックする方法 - Windchaseに書かれた方法を試したところタッチイベントを取得できるようになりました。この方法は UIWebViewが継承している UIDocumentView クラスというWebViewの実体(?)である非公開のクラスの持っているタッチイベントメソッドを書き換えて タッチイベントを デリゲートするという力業を使っています。
しかし、このコードは iOS4 (たぶん iOS3.2)では動きません。iOS3.2からはUIDocumentViewクラスがUIWebBrowserViewクラスに変わっていますが、そこを変更しただけでは動きませんでした。
UIWindowのイベントをデリゲートする
そこで次に試したのは [iPhone] UIWebView のタッチイベントを取得する | Sun Limited Mt. でした。これは iOS4でもiOS3.1 でも動作しました。
この方法は、画面に対する全てのイベントを受け取れる UIWindow のイベント処理メソッドで上に乗っている UIWebView関連のタッチイベントのみをデリゲートするという、まっとうなやり方です。
しかし、ここに書かれた GestureWindow という UIWindowクラスをカスタマイズ(継承)したクラスを使うと画面の auto rotate (iPhoneの画面を横向きに対応させたりする機能) が正しく動かなくなってしまいました ^^);
いろいろと試したのですが、ダメで twitter につぶやいてみました。
すると、神の声 岸川さん が GestureWindowクラスのdelegateという名前のインスタンス変数(プロパティー) がまずいんじゃない? というつぶやきが !!
早速、delegateという名前のインスタンス変数(プロパティー) を wDelegateに変更したところ auto rotate も機能するようになりました !!
ドキュメント上では UIWindowと、継承しているクラスには delegateプロパティーが在るように書かれていませんが、実は存在するようです・・・・・
ということで 岸川さん ありがとうございます m(_ _)m







