ラベル cocos2dx の投稿を表示しています。 すべての投稿を表示
ラベル cocos2dx の投稿を表示しています。 すべての投稿を表示

2015年9月9日水曜日

[XCode]【Your account already has a valid iOS Distribution certificate】AdHoc出力できないときの対処方法

エラー


Your account already has a valid iOS Distribution certificate
If you have your signing identity on another Mac, you can import a developer profile.
You can also revoke the current certificate and request one again.

背景

Macを新しくしてから、以前に作成したアプリをAdHoc出力しようとしたときに出たエラーです。

Provisioning Profiles は確かに新しくしたはず。
実機でデバッグもできるし、特に問題なくいけていると思っていたのに・・・

いろいろな原因があるのだと思うが、私の場合は次の方法で解決ができました。


2015年8月7日金曜日

[XCode] アプリ作成時によく見るエラーとその解決法 まとめ


はじめに

XCode(Objective-C)でよく見るエラーや警告を集めました。

前々からこういう整理した記事が個人的に欲しかったので作ってみました。

解決方法はざっくりと書きます。
詳細な解決方法はリンク先の記事(当ブログ記事や別サイト記事)に委ねます。

この記事は随時、追加や更新をして、今後どんどん育てていく予定です。
参照するたびに変更になっている可能性があります。ご了承ください。
今後、当ブログでエラーの記事を書いた場合は、別途記事を書いた上で、ここにリンクする予定です。

では、始めてまいりましょう。

2015年7月29日水曜日

[cocos2dx] でローカライズに対応する【LocalizedString】


ローカライズ関数を用意した理由

理由も何もないんですが、cocos2d-xで気軽にObjective-cで利用できるようなローカライズ関数が欲しいなと思い、作成しました。

今回はそんなローカライズ関数です。



実際の関数

はじめに。
この関数は以下の記事の関数を利用しています。
cocos2d-xで文字列を置換する【Replace】
cocos2dでトリミング関数を作る【trim】
cocos2d-xで文字列をデリミタで分解しリスト化する関数を作る【split】

次にこの関数を利用するには、[ja.lproj]や[en.lproj]などのLanguageごとのフォルダを用意し、それぞれにローカライズファイル[Localizable.strings]用意する必要があります。
【ja.lproj/Localizable.strings】
test=テスト
hogehoge=ほげほげ
【en.lproj/Localizable.strings】
test=Test
hogehoge=HogeHoge

【注意】
ローカライズファイル[Localizable.strings][File Type]は、[Localizable Strings]から[Plain Text]に変更して進める必要があります。
これをしておかないと、コンパイル時にファイルが最適化され、getStringFromFile()によるロードがうまくいきません。



使い方


こんな感じで使います。
std::string result = LocalizedString("hogehoge", "ほげほげの取得");
//result は日本語環境では "ほげほげ" となります
//result は英語環境では "Hogehoge" となります

簡単な説明

static map<std::string, std::string> localizable;
ローカライズ文字列のマップデータは、静的変数にセットすることで、無駄なファイル解析を避けます。

if(localizable.empty()){
ローカライズ文字列のマップデータがない場合に、1度だけローカライズファイルを解析します。

FileUtils* fileUtil = FileUtils::getInstance();
LanguageType language = Application::getInstance()->getCurrentLanguage();
if (language == LanguageType::JAPANESE) {
    fileUtil->addSearchPath("ja.lproj");
if (language == LanguageType::★★★★) {  //ローカライズしたいLanguageTypeを指定
    fileUtil->addSearchPath("★★★★");   //LanguageTypeごとのフォルダを指定
} else {
    fileUtil->addSearchPath("en.lproj");
}
ローカライズファイルのあるディレクトリを検索対象パスに追加します。

std::string fullpath = fileUtil->fullPathForFilename("Localizable.strings");
std::string strings = fileUtil->getStringFromFile(fullpath);
if (strings == "") return ret;
ローカライズファイル(Localizable.strings)を読み込みます。

list<std::string> stringLines = split(strings, "\n");
行ごとに分解して、以降の処理を実施します。

for(list<std::string>::iterator begin = stringLines.begin(), end = stringLines.end(); begin != end; ++begin){
    list<std::string> stringKeyValue = split(*begin, "=");
    if(stringKeyValue.size() >= 2){
        list<std::string>::iterator keyv = stringKeyValue.begin();
        localizable.insert(pair<std::string, std::string>(*keyv, *(++keyv)));
    }
}
1行ごととり出し、"="でkeyとvalueに切り出し、ローカライズ文字列のマップデータに設定します。

map<std::string, std::string>::iterator iterator = localizable.find(searchKey);
if(iterator != localizable.end()){
    ret = iterator->second.c_str();
}
ローカライズ文字列のマップデータから、対象のデータを取り出し返却します。

std::string result = stringReplace(ret, "\\n", "\n");
最後に対象データの改行をケアしています。


このプログラムが皆様のお役に立てば幸いです。

ではまた。


2015年7月28日火曜日

[cocos2dx] で文字列をデリミタで分解しリスト化する関数を作る【split】


文字列のデリミタ分解する関数を用意した理由

文字列を分解して作業したい場合があります。
分解した文字列はリスト化して便利に取り出して利用することができます。

私の場合、設定値を文字列にしたものをロードしたり、csv分解したりするのに利用しました。

今回はそんな文字列をデリミタで分解しリスト化する関数です。



実際の関数

はじめに。
この関数は以下の記事の関数を利用しています。
cocos2dでトリミング関数を作る【trim】


使い方


こんな感じで使います。
std::string result = split("I;My;Me;Mine", ";");
//result は "I","My","Me","Mine" のリストが返却されます。

簡単な説明

while( (cutAt = str.find_first_of(delim)) != str.npos ) {
デリミタ文字を検索し、ループします。

if(cutAt > 0) {
    result.push_back(trim(str.substr(0, cutAt)));
}
デリミタ文字までの文字列を結果リストに追加します。

str = str.substr(cutAt + 1);
次の準備のために、追加した文字列分は切り落とします。

if(str.length() > 0) {
    result.push_back(trim(str));
}
上記ループでは最後が追加されないので、残りの文字列を結果リストに追加します。



このプログラムが皆様のお役に立てば幸いです。

ではまた。

2015年7月27日月曜日

[cocos2dx] でトリミング関数を作る【trim】


文字列のトリミング関数を用意した理由

スペースだけのトリミングはよくあるんですが、スペースはもちろんのこと改行やデリミタも含めてトリミングできたらなーと思って作りました。

今回はそんな文字列のトリミング関数です。



実際の関数



使い方


こんな感じで使います。
std::string result = trim("I am Tom;  ");
//result は "I am Tom" となります

簡単な説明

std::string::size_type left = str.find_first_not_of(trimCharacterList);
対象文字(デリミタ文字)の含まれない左端を取得します。

if (left != std::string::npos) {
左端の取得に成功した場合は以下の処理を続行します。

std::string::size_type right = str.find_last_not_of(trimCharacterList);
対象文字(デリミタ文字)の含まれない右端を検索します。

result = str.substr(left, right - left + 1);
最後に左端から右端までをtrim内容として取得し、返却します。



このプログラムが皆様のお役に立てば幸いです。

ではまた。


2015年7月26日日曜日

[cocos2dx] で文字列を置換する【Replace】


文字列の置換関数を用意した理由

画面に見える文字列を整形する場合なんかは「StringUtils::format」でほとんどがなんとかなるんだけれど、内部データを整形する場合(例えばデリミタを置換したり、改行を入れてみたり)なんかは、文字列をまるっと置換できる仕組みがあったほうが嬉しかったりします。

今回はそんな文字列の置換関数です。



実際の関数



使い方


こんな感じで使います。
std::string result = stringReplace("I am Tom", "Tom", "Hogehoge");
//result は "I am Hogehoge" となります

簡単な説明

while(pos = result.find(from, pos), pos != std::string::npos) {
まずターゲットとなる文字列の開始位置を検索しながらループします。

result.replace(pos, from.length(), to);
次にターゲットとなる文字列を、置換する文字列に変換します。

pos += to.length();
ループの最後で次の文字列検索の準備をしています。



このプログラムが皆様のお役に立てば幸いです。

ではまた。


2015年7月24日金曜日

[Objective-C] iOSアプリにソーシャル機能を組み込む【実践編】

はじめに

以前に投稿した下の記事でソーシャル機能の分析と目的、効果について少し書きました。
人気アプリから学ぼう 「ねこあつめ」その5:ソーシャル機能を分析しよう!編

今回はそれの実践編です。

基本的にはコードを見てもらえば、理解していただけると思うのですが、それぞれ少しづつ注意点があるので、確認してください。




Facebookへの投稿

利用するには、Social.frameworkの追加が必要です。


【簡単な説明】
SLComposeViewController *facebookPostVC = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
[facebookPostVC setInitialText:text];
[facebookPostVC addURL:[NSURL URLWithString:url]];
[facebookPostVC addImage:[UIImage imageNamed:image]];
[facebookPostVC setCompletionHandler:^(SLComposeViewControllerResult result) {
    if (result == SLComposeViewControllerResultDone) {
        //投稿完了の処理
    }
}];
[ViewController presentViewController:facebookPostVC animated:YES completion:nil];
SLComposeViewControllerを利用して、Facebookに対し、投稿テキスト、URL、イメージを投稿しています。
投稿完了時にはイベントを受け取り、投稿のお礼メッセージや、プレゼントなど処理をします。


Twitterへの投稿

利用するには、iOSバージョンごとに適切なframeworkの追加が必要です。
iOS6.0以上の場合、Social.frameworkの追加が必要
iOS5.0以下の場合、Twitter.frameworkの取り込みが必要


【簡単な説明】
NSString *iosVersion = [[[UIDevice currentDevice] systemVersion] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
if ([iosVersion floatValue] >= 6.0) {
}
else if ([iosVersion floatValue] >= 5.0) {
}
iOSのバージョンで、Social.frameworkを使うか、Twitter.frameworkを利用するかを決定しています。

SLComposeViewController *twitterPostVC = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
[twitterPostVC setInitialText:text];
[twitterPostVC addURL:appURL];
[twitterPostVC addImage:[UIImage imageNamed:image]];
[twitterPostVC setCompletionHandler:^(SLComposeViewControllerResult result) {
    if (result == SLComposeViewControllerResultDone) {
        //投稿完了の処理
    }
}];
[ViewController presentViewController:twitterPostVC animated:YES completion:nil];
SLComposeViewControllerを利用して、Twitterに対し、投稿テキスト、URL、イメージを投稿しています。
投稿完了時にはイベントを受け取り、投稿のお礼メッセージや、プレゼントなど処理をします。

Lineへの投稿

frameworkは必要ないですが、テキストとイメージが別々にしか投稿できません。
また、投稿完了を受取ることができないので、利用には注意が必要です。


【簡単な説明】
text = [text stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *LINEUrlString = [NSString stringWithFormat:@"line://msg/text/%@", text];
LINEに文字列を投稿するためのURLを作成します。
LINEへは「line://msg/text/(投稿したい文字列)」というURLスキーマを利用して投稿することになります。

//iOS7.0以降では共有のクリップボードを使う必要がある
UIPasteboard *pasteboard;
if ([[UIDevice currentDevice].systemVersion floatValue] >= 7.0) {
    pasteboard = [UIPasteboard generalPasteboard];
} else {
    pasteboard = [UIPasteboard pasteboardWithUniqueName];
}
[pasteboard setData:UIImagePNGRepresentation(image) forPasteboardType:@"public.png"];
NSString *LINEUrlString = [NSString stringWithFormat:@"line://msg/image/%@", pasteboard.name];
LINEにイメージを投稿するためのURLを作成します。
投稿にはUIPasteboardを利用します。
LINEへは「line://msg/text/(投稿イメージ名)」というURLスキーマを利用して投稿することになります。

if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:LINEUrlString]]) {
LINEアプリがインストールされているか確認します。
インストールされていない場合は、LINEアプリのストアへ遷移などしてもよいかもしれません。

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:LINEUrlString]];
LINEへ投稿します。
LINEは投稿完了を受け取れないため、メソッドコールと投稿完了がイコールとなります。


2015年2月4日水曜日

[cocos2dx] v3.3にAdMob SDK 6.12.2(iOS)を入れた時のリンクエラー対処

cocos2d-x v3.3にAdMob SDK 6.12.2(iOS)を入れた時にリンクエラーがわんさか出てきて焦ったのでメモ。


原因はAdMob SDK 6.12.2(iOS)を導入時にOther Linker Flagsに-ObjCを設定したことによるもののようですが、分かりにくいな。


導入時に大量のフレームワークを導入させられるわけですが、これだけでは足りず、以下の3つのフレームワークをさらに導入が必要でした。

まずは、以下を参考にたりないフレームワークを追加。
  • MediaPlayer
  • GameController (iOS6対応アプリの場合はoptional)
この辺は下記のブログを参考にさせていただきました。
cocos2d-x v3.2にiOS版AdMob SDK 6.12.0を導入した時のリンクエラーの対処

うーんこれでもエラーが消えない。
どうやらsqliteのフレームワークがないとのこと。

  • libsqlite3.0.dylib

うーん、導入ガイドに書いとけよなと思いつつ、
これらは事前に導入されていることが前提なのだろうか。。。
と考えさせられた一件でした。


    2013年3月20日水曜日

    [XCode/cocos2dx] 画面解像度対応

    iPhoneアプリはいくつか作ったけれど、ゲームが作りたくなり、しばらくまえからスマホでゲームを作ろうと四苦八苦しています。

    クロスプラットフォームを意識して、開発環境の策定に翻弄し、enchant.jsから始まりいろいろ試した結果、最終的にはやはりというかなんというかcocos2d-xに落ち着きました。物理エンジン(box2d)を利用したいです。

    これからはcocos2d-xもからめてブログを書いていきたいと思います。
    まずは解像度対応から



    cocos2dx画面解像度対応

    coco2dxのテンプレートで新規プロジェクト作成後、4-inch画面に対応するには、スプラッシュ画面(LunchImages)を設定すれば認識してくれるみたいです。


    解像度に関しては@2xが推奨されていないようで、フォルダ単位で画像を分けることになります。


    あとは、AppDelegate::applicationDidFinishLaunching{} で以下の関数を呼ぶようにすれば画面解像度には対応できました。


    この関数では、以下の2点を設定しています。
    • 開発ベースサイズの調整(480x320ベースで実装を行う(4inchのみ568x320))
    • イメージ取得フォルダの調整
    イメージは以下のそれぞれのフォルダより取得されることになります。
    • @2x -> Resources/Published-iOS/resources-iphoneh
    • 通常 -> Resources/Published-iOS/resources-iphone

    どうやら、以下の2つのメソッドは[cocos2d-2.0-x-2.0.4]にはないようで、[cocos2d-2.1beta3-x-2.1.1]にて確認がとれました。(ソース読む必要があり、ここにかなりはまった...)

        CCFileUtils::sharedFileUtils()->setSearchPaths(searchPaths);
        CCFileUtils::sharedFileUtils()->setSearchResolutionsOrder(resDirOrders);

    参考