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
..