CocoaのFrameworkでSTLを使ってみる

最近Cocoaにはまっています。Windows用に作成したライブラリをMacへ移植してみたのですが意外とはまったのでメモ

環境

  • MacOX10.9
  • XCode 5

TestAppという単純なアプリを作成しその中からSTLで作成したFrameworkを呼ぶことにするサンプルです。

UtilsというなのFramework

まず、ライブラリの作成です。XCodeでOSX用のCocoaFrameworkを作成します。

作成した後にファイルの追加で以下のヘッダファイルとC++ファイルを追加します

  • Test.h
#ifndef Utils_Test_h
#define Utils_Test_h
#include 
// 値を保持するクラス
class Bean{
public:
		int a;
		int b;

		Bean();
		void set(int a,int b);
		std::string to_s();
};
// 値を操作するクラス
class Test{
public:
		int add(int a,int b);
		std::shared_ptr add(std::shared_ptr a ,std::shared_ptr b);
};
#endif
  • Test.cpp
#include "Test.h"
#include 
Bean::Bean(){
		a=0;
		b=0;
}
void Bean::set(int a_,int b_){
		a=a_;
		b=b_;
}
std::string Bean::to_s(){
		char buf[1000];
		sprintf(buf,"a=%d,b=%d",a,b);
		return std::string(buf);
}
int Test::add(int a, int b){
		return a+b;
}
std::shared_ptr Test::add(std::shared_ptr a ,std::shared_ptr b){
		std::shared_ptr ret=std::shared_ptr(new Bean());
		int va=a->a+b->a;
		int vb=b->b+b->b;
		ret->set(va,vb);
		return ret;
}

ついでにObjective-Cのクラスも追加します。こちらを参考に

  • Utils.h
#import 

@interface Utils : NSObject
+(NSString*)addBrackets:(NSString*)string;
@end
  • Utils.m
#import "Utils.h"

@implementation Utils
+(NSString *)addBrackets:(NSString *)string
{
		return [NSString stringWithFormat:@"[-- %@ --]", string];
}
@end

それぞれのヘッダファイルをPublickにしたのちに、コンパイルするのですが、Build Rulesの Apple LLVM 5.0 Language C++のC++ Language Dialect を -std=c++11へ、C++ Standard Libraryを libc++(LLVM C++ standard library with C++ 11 supportへ変更します。また Apple LLVM 5.0 Language のCompile Source As をObjective-C++へと変更しておきます。

これでコンパイルOKのはず

TestAppというアプリ作成

OSXのApplicationのCocoaApplicationからプロジェクトを作成し、テキストボックスとボタンを配置しておきます。また、プロジェクトのFrameworksに先ほど作成したUtilsのフレームワークを追加しておきます。

  • AppDelegate.h
#import 

@interface AppDelegate : NSObject 

@property (assign) IBOutlet NSWindow *window;

@property IBOutlet NSButton *button;
@property IBOutlet NSTextField *text;

-(IBAction)pushButton:(id)sender;
@end
  • AppDelegate.m
#import "AppDelegate.h"

#import 
#import 
#include 

@implementation AppDelegate
@synthesize button;
@synthesize text;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
		// Insert code here to initialize your application
}

-(IBAction)pushButton:(id)sender{
		std::shared_ptr a=std::shared_ptr(new Bean());
		std::shared_ptr b=std::shared_ptr(new Bean());
		std::shared_ptr t=std::shared_ptr(new Test());

		a->set(1,2);
		b->set(10,20);
		std::shared_ptr tt=t->add(a,b);
		NSString* swk=[NSString stringWithCString:tt->to_s().c_str() encoding:[NSString defaultCStringEncoding]];
		NSString* str=[Utils addBrackets:swk];
		[text setStringValue:str];
}
@end

先ほどのライブラリと同様にBuildSettingを変更しておきます。

これでコンパイルとリンクがOKのはず。。

ボタンを押すとライブラリで計算した値がテキストボックスに出るはずです

Mac用アプリの自動テスト

最近自動テストツールにはまっています。

さすがにはやりというかiOSやAndroid用のテストツールは山ほど(というほどでもありませんが)有るのですが、Macのアプリ用のテストツールはほとんど有りません。

ちなみにこちらにまとめて書いてあるので参考になります

http://iphone-dev.g.hatena.ne.jp/laiso/20120111/1326280021

KIFのMac版が有るとのことなのでちょっと試してみました。

こちらのサイトを参考に

http://d.hatena.ne.jp/laiso+iphone/20121013/1350134198

環境

  • MacOS10.9
  • Xcode 5

この組み合わせで少しはまりました。

http://d.hatena.ne.jp/laiso+iphone/20121013/1350134198

こちらのサイトのサンプルであるGITHubからダウンロードします

https://github.com/laiso/Mac-Samples/tree/master/KIFMac01

git clone https://github.com/laiso/Mac-Samples.git

このままではKIFがとれないので別途取得します

mkdir work
cd work
git init
mkdir Vendor
git submodule add https://github.com/joshaber/KIF.git	Vendors/KIF-Mac

先ほど取得したサンプルに上書きします

mv Vendors/KIF-Mac ../../Mac-Sample/.

Xcodeを起動しプロジェクトを取り込みます

IntegrationTestのターゲットを選んで実行。しても止まってしまいます。

ログを見ると、

System Preferences => Universal Access => Enable access for assistive devices

どうやらアクセシビリティがだめな模様。

システム環境設定のアクセシビリティを見ても設定項目なし。。

http://www.tekrevue.com/how-to-enable-access-for-assistive-devices-in-os-x-mavericks/

こちらに答えが書いていました。

システム環境設定のセキュリティとプライバシーの中から、プライバシータグのアクセシビリティにXCodeのチェックボックスをオン

これでサンプル通りに動きました

npmコマンドのproxy設定

iOSとAndroidのアプリのテストが自動でできるというappiumを試そうとしたときの話。

  • 環境
    • MacOS 10.9
  • インストール
$ brew install node
Warning: node-0.10.24 already installed
$ sudo npm install -g appium
Password:
npm http GET https://registry.npmjs.org/appium
npm http GET https://registry.npmjs.org/appium
npm http GET https://registry.npmjs.org/appium
npm ERR! network read ECONNRESET
npm ERR! network This is most likely not a problem with npm itself
npm ERR! network and is related to network connectivity.
npm ERR! network In most cases you are behind a proxy or have bad network settings.
npm ERR! network
npm ERR! network If you are behind a proxy, please make sure that the
npm ERR! network 'proxy' config is set properly.	See: 'npm help config'
npm ERR! System Darwin 13.0.0
npm ERR! command "/usr/local/Cellar/node/0.10.24/bin/node" "/usr/local/bin/npm" "install" "-g" "appium"
npm ERR! cwd /private/tmp
npm ERR! node -v v0.10.24
npm ERR! npm -v 1.3.21
npm ERR! syscall read
npm ERR! code ECONNRESET
npm ERR! errno ECONNRESET
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR!		 /private/tmp/npm-debug.log
npm ERR! not ok code 0

こんな感じでおこられてしまった

proxyの設定はbashの環境変数とは別の様でconfigで設定する必要が有ります

$ npm config set proxy http://proxyhost:8080

再度実行

$ sudo npm install -g appium
Password:
npm http GET https://registry.npmjs.org/appium
npm http 200 https://registry.npmjs.org/appium
npm http GET https://registry.npmjs.org/appium/-/appium-0.13.0.tgz
npm http 200 https://registry.npmjs.org/appium/-/appium-0.13.0.tgz
npm http GET https://registry.npmjs.org/grunt
npm http GET https://registry.npmjs.org/argparse
npm http GET https://registry.npmjs.org/uuid-js
npm http GET https://registry.npmjs.org/rimraf
..

macを10.9.1にバージョンアップしたらmac->winのSynergyでバックスラッシュが効かなくなってしまった場合の対処

サーバ側

  • MacOS 10.9
  • SynergyKM

クライアント側

  • windows7
  • Synergy1.3.1a-ja

こちらを参考に、http://wiki.nothing.sh/page/memo/Synergy 上記構成でMacをサーバにWindowsをクライアントとしてSynergyを使っていたのですが、どうやら10.9.1にバージョンアップしたらWindows側でバックスラッシュ「¥」が効かなくなってしまいました。

10.9.1のReleaseNoteをチラッと見ると、日本語入力周りの修正等と書いてあったのでもしやこれに引っかかったか?

非常に不便なので、ダメ元でWindows側のSynergyを1.3.1-jaに変更。

どうせ一緒だものね。

と、なんと、これでバックスラッシュが効くようになったとさ。

今回のMacOSのアップデートで、どうやらずいぶんと前からある不具合を直したのでしょうか?

LinuxからMac10.9へリモートディスプレイでX上のFirefoxを動かす

ちょっとはまったのでメモ。

通常X-Windows同士はお互いに、リモートでディスプレイ上のものを映すことができます。

A:Linux

B:Linux

A->BへsshでログインしBのFirefoxを起動しAのX上で操作するということです。

意外とこれが便利。

X-Windowを搭載しているMacでも同じことが当然できるはず。

ということで試してみる

古い記憶を辿りながら

Local

mac 10.9(hostname:mac,ip:192.168.0.1)

remote

RedHat 5.8 (hostname:linux,ip:192.168.0.2)

Macでの設定

[mac] $ xhost +

Linux側での設定

[mac] $ ssh linux
[linux] $ export DISPLAY=192.168.0.1:0
[linux] $ firefox
Error: cannot open display: 192.168.0.1:0

これが起動しない。

こちらに解決法が。。

http://ruepprich.wordpress.com/2013/01/08/x11-forwarding-on-os-x-10-8-2-mountain-lion/

Macでの設定

[mac] $ sudo xhost + linux

Linux側での設定

[mac] $ ssh -X linux
[linux] $ firefox

見事にMac側にFirefoxのウインドウが。。

DISPLAYは必要ないのね。。

marveriksにアップデートしたらSynergyのキー配列が変

以前Windowsをサーバにmacをクライアントでsynergyを使用していたのですが、macのOSをmountain lion からmavericksにアップデートしたところ、synergyで記号がまたまたおかしくなってしまった

以前はキーボードの設定で地域をオーストラリアなどにすればよかったのですが今回はそういう設定がなくなった模様。。

いろいろごじゃごじゃやってようやく解決

  • mac 10.9 + SybergyKM
  • windows 7 + Synergy1.3

1.macのシステム設定からキーボードを選択

2.入力ソースで+からbritish-PCを選択

3.ことえりを選択し英字のチェックを外す

つまり英語入力時にはbritish-PCを使えば106キーボードの記号がそのまま出ます

そろそろバグ修正してもらえませんかねぇ

MacOS10.8のVirtualBox上でUSB接続のDVDを認識させる

  • iMac MacOS10.8
  • DVD Drive Buffalo BRXL-PC6VU2
  • ゲストWindowsVista Ultimate 32bit

この組み合わせでVirtualBox上のVistaにつなげるにはちょっと苦労しました。

VirtualBoxの設定からポート、USB を選択し+ボタンでBUFFALO Optical ODDを追加します。この際にUSB2.0コントローラを有効にしますが、こちらはVirtualBoxの追加パッケージを入れておく必要がありました。

このまま起動すると、Vista上では不明なデバイスとして認識されてしまい、DVDは使えません。

ネットを調べたところ皆さん苦労しているようで、起動前にUSBをMacから物理的にはなしておき、VirtualBox起動後につけるとかあったのですが、うまくいきません。

半ばあきらめていたのですが、OKWebにあったこれ

「CPUを一個にするとうまくいく!」

半信半疑でVirtualBoxのCPU数を2個から1個へ。

これがうまくいきました。Explorer上でちゃんとDVDドライブとして認識されています

Macでkakasi

KAKASIをMacにインストールしてみた

  • MaxOS10.8.2
  • kakasi-2.3.4
$ tar zxvfp kakasi-2.3.4.tar.gz
$ ./configure
$ make
make	all-recursive
Making all in src
make[2]: Nothing to be done for `all'.
Making all in lib
/bin/ksh ../libtool --mode=link gcc	-g -O2 -Wall -Wunused -Wuninitialized -Wmissing-prototypes -Wmissing-declarations -pedantic	-o libkakasi.la -rpath /usr/local/lib -version-info 3:0:1	-export-dynamic libdict.lo libkakasi.lo libkanjiio.lo liba2.lo libg2.lo libj2.lo libk2.lo libee2.lo libhh2.lo libjj2.lo libkk2.lo libitaiji.lo lib78_83.lo
rm -fr .libs/libkakasi.la .libs/libkakasi.* .libs/libkakasi.*
gcc -dynamiclib -undefined suppress -o .libs/libkakasi.2.1.0.dylib	libdict.lo libkakasi.lo libkanjiio.lo liba2.lo libg2.lo libj2.lo libk2.lo libee2.lo libhh2.lo libjj2.lo libkk2.lo libitaiji.lo lib78_83.lo	-lc -install_name	/usr/local/lib/libkakasi.2.dylib -compatibility_version 4 -current_version 4.0
ld: can't use -undefined warning or suppress with -twolevel_namespace
collect2: ld returned 1 exit status
make[2]: *** [libkakasi.la] Error 1
make[1]: *** [all-recursive] Error 1
make: *** [all-recursive-am] Error 2

エラーが出る

http://www.ki.nu/~makoto/diary/?200307b&to=200307131#200307131

こちらに対処法があったので修正

$ vi libtool
allow_undefined_flag="-undefined suppress"
↓
allow_undefined_flag=""
$make
#make install
$ echo "書かし"|kakasi.dSYM -Ja -Ka -Ha
kakashi

うまくいったようだ

memcachedで日本語キーを扱う

memcachedの代わりにkyoto tycoonを試してみようとしています。

kyoto tycoonはmemcachedと同じインターフェースで起動できるとのことで、当然memcachedライブラリが使えます

日本語のキーが使えるかどうか確認します

  • memcachedライブラリ
$ su
# export http_proxy=proxy:port
# gem install memcached
#!/bin/env ruby -Ku 
# -*- encoding:utf-8 -*-
require "rubygems"
require "memcached"
require "nkf"

cache=Memcached.new "localhost:11211"
cache.set("sony","6758",0)
puts cache.get("sony")
key="ソニー"
cache.set(key,"ソニー",0)
puts cache.get(key)
$ ruby mem.rb 
6758
/Library/Ruby/Gems/1.8/gems/memcached-1.5.0/lib/memcached/memcached.rb:630:in `reraise': Key {"ソニー"=>nil} (Memcached::ABadKeyWasProvidedOrCharactersOutOfRange)
	from /Library/Ruby/Gems/1.8/gems/memcached-1.5.0/lib/memcached/memcached.rb:608:in `check_return_code'
	from /Library/Ruby/Gems/1.8/gems/memcached-1.5.0/lib/memcached/memcached.rb:306:in `set'
	from mem.rb:11

なんかだめ。。

ちなみにperlだと

#!/usr/bin/perl

use strict;
use warnings;
use Cache::Memcached::Fast;

my $memd=Cache::Memcached::Fast->new({
		servers => [ { address => 'localhost:11211' }], 
}); 

# 値を追加 key => value
my $key='ソニーal';
$memd->set($key=> 'そにー2');

# 値を取得
my $id = $memd->get($key);
print "$id\n";
$ perl mem.pl
そにー2

rubyのライブラリが悪いようだ

ちなみにOSはMountain Lion

vimのシンタックスハイライトにscalaを追加する

macでscalaを使うためにはbrewでインストールするのが一番簡単です

brew install scala

このままだとvimで.scalaを開いた際に色がつかないので非常にみづらいです

いろいろやり方はあるみたいですがこれが一番簡単でした

http://bsnyderblog.blogspot.jp/2012/12/vim-syntax-highlighting-for-scala-bash.html

mkdir -p ~/.vim/{ftdetect,indent,syntax} && for d in ftdetect indent syntax ; do wget --no-check-certificate -O ~/.vim/$d/scala.vim https://raw.github.com/scala/scala-dist/master/tool-support/src/vim/$d/scala.vim; done