2013年10月23日水曜日

cocos2dでTextField

CCUIViewWrapperを使用

以下のURLよりソースを取得

※そのままではBuild時に警告が出るので以下を修正
[[[[CCDirector sharedDirector] view] window] addSubview: uiItem];
//[[[CCDirector sharedDirector] openGLView] addSubview:uiItem];

/****************************************/

//if(!p.isRelativeAnchorPoint)
if(p.ignoreAnchorPointForPosition)
    transform = CGAffineTransformTranslate(transform, p.anchorPoint.x, p.anchorPoint.y);
    //transform = CGAffineTransformTranslate(transform, p.anchorPointInPixels.x, p.anchorPointInPixels.y);

/****************************************/

transform = CGAffineTransformTranslate(transform, -p.anchorPoint.x, -p.anchorPoint.y);
//transform = CGAffineTransformTranslate(transform, -p.anchorPointInPixels.x, -p.anchorPointInPixels.y);


UITextFieldを実装

ヘッダー

@interface GameLayer : CCLayer <UITextFieldDelegate> {
    CCUIViewWrapper *textFieldWrapper;
    UITextField *textBox;
}
@end

実装

- (void)addTextField {
    textBox = [[[UITextField alloc] init] autorelease];
    textBox.frame = CGRectMake(175, 120, 110, 25);
    textBox.borderStyle = UITextBorderStyleRoundedRect;
    textBox.placeholder = @"hogehoge";
    textBox.returnKeyType = UIReturnKeyDone;
    textBox.clearButtonMode = UITextFieldViewModeWhileEditing;
    textBox.autocapitalizationType = UITextAutocapitalizationTypeNone;
    textBox.enablesReturnKeyAutomatically = YES;
    textBox.contentVerticalAlignment = UIControlContentHorizontalAlignmentCenter;
    textBox.textAlignment = NSTextAlignmentCenter;
    textFieldWrapper = [CCUIViewWrapper wrapperForUIView:textBox];
    textBox.delegate = self;
    [self addChild:textFieldWrapper];
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    [textField resignFirstResponder];
    return YES;
}

- (void)textFieldDidEndEditing:(UITextField *)textField {
    CCLOG(@"text->%@", textBox.text);
}

URL encode/decode

//encoding
NSString *escapedUrlString = (NSString *)CFURLCreateStringByAddingPercentEscapes(
        NULL,
        (CFStringRef)plainString,
        NULL,
        (CFStringRef)@"!*'();:@&=+$,/?%#[]",
        kCFStringEncodingUTF8 );
 
//decoding
NSString *decodedUrlString = (NSString *) CFURLCreateStringByReplacingPercentEscapesUsingEncoding(
        NULL,
        (CFStringRef) escapedUrlString,
        CFSTR(""),
        kCFStringEncodingUTF8);

XMLパーサー

ヘッダー

@interface XMLParserWrapper : NSObject <NSXMLParserDelegate> {
    NSString *searchElementString;
}

- (void)parseXMLFileAtURL:(NSURL *)URL parseError:(NSError **) error ;
- (void)parseXMLFileAtData:(NSData *)data parseError:(NSError **) error ;

@end


実装

@implementation XMLParserWrapper

//URLで解析
- (void)parseXMLFileAtURL:(NSURL *)URL parseError:(NSError **) error {
    NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:URL];
    [self parseXMLFile:parser parseError:error];
}

//Dataで解析
- (void)parseXMLFileAtData:(NSData *)data parseError:(NSError **) error {
    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
    [self parseXMLFile:parser parseError:error];
}

- (void)parseXMLFile:(NSXMLParser *)parser parseError:(NSError **) error {
    [parser setDelegate:self];
    [parser setShouldProcessNamespaces:NO];
    [parser setShouldReportNamespacePrefixes:NO];
    [parser setShouldResolveExternalEntities:NO];
    [parser parse];
    NSError *parseError = [parser parserError];
    if (parseError && error) {
        *error = parseError;
    }
    [parser release];
}

- (void)parserDidStartDocument:(NSXMLParser *)parser {
    searchElementString = nil;
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
    if ([elementName isEqualToString:@"取得したい属性名"]) {
        searchElementString = [NSString stringWithString:elementName];
    }
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {

    if ([elementName isEqualToString:@"取得したい属性名"]) {
        searchElementString = nil;
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    if ([searchElementString isEqualToString:@"取得したい属性名"]) {
        //stringに取得したい属性の値
    }
}

@end



使い方

NSError *parseError = nil;
XMLParserWrapper *parser = [[XMLParserWrapper alloc] init];
[parser parseXMLFileAtData:receivedData parseError:&parseError];

if (parseError) {
    //parseエラー
    NSLog(@"Parse Error->%@", parseError);
}

非同期通信

NSMutableData *receivedData;

//非同期通信
- (void)startConnection{
    
    NSURL *url = [NSURL URLWithString:@"http://xxxx.jp/"];
    NSURLRequest *request=[NSURLRequest requestWithURL:url];
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
    
    if (!connection) {
        //エラー
    }
}


//通信開始
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    receivedData = [[NSMutableData data] retain];
}

//通信中(何度も呼ばれる)
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
    // データを追加する
    [receivedData appendData:data];
}

//通信終了
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    NSString *dataStr = [[[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding] autorelease];
    //受信データをログに表示
    NSLog(@"%@", dataStr);
    
    [receivedData release];
    receivedData = nil;
    [connection release];
}

//通信エラー
- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    //アラートを出す
    NSString *erroMessage = [error localizedDescription];
    UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@"Error" message:erroMessage delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease];
    [alert show];
}

2013年10月15日火曜日

Google Analytics for iOS v3(Beta)

※注意:この内容は古い情報です


以下に最新(2014/2/27 ver3.0.3c)の情報を記載したのでそちらを参照ください。
http://kojisatoapp.blogspot.jp/2014/02/iosgoogle-analytics.html


ライブラリ追加


  • GAI.h
  • GAITracker.h
  • GAITrackedViewController.h
  • GAIDictionaryBuilder.h
  • GAIFields.h
  • GAILogger.h
  • libGoogleAnalyticsServices.a



フレームワークの追加


  • AdSupport.framework
  • libGoogleAnalyticsServices.a
  • CoreData.framework
  • SystemConfiguration.framework
  • libz.dylib



初期処理

#import "GAI.h"

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

  // Optional: automatically send uncaught exceptions to Google Analytics.
  [GAI sharedInstance].trackUncaughtExceptions = YES;

  // Optional: set Google Analytics dispatch interval to e.g. 20 seconds.
  [GAI sharedInstance].dispatchInterval = 20;

  // Optional: set Logger to VERBOSE for debug information.
  [[[GAI sharedInstance] logger] setLogLevel:kGAILogLevelVerbose];

  // Initialize tracker.
  [[GAI sharedInstance] trackerWithTrackingId:@"UA-XXXX-Y"];

}


ページのトラッキング(自動計測)

#import "GAITrackedViewController.h"

@interface HomeViewController : GAITrackedViewController

- (void)viewDidAppear:(BOOL)animated {
  [super viewDidAppear:animated];
  self.trackedViewName = @"About Screen";
}


ページのトラッキング(手動)

#import "GAI.h"
#import "GAIFields.h"
#import "GAIDictionaryBuilder.h"

// May return nil if a tracker has not already been initialized with a
// property ID.
id tracker = [[GAI sharedInstance] defaultTracker];

// This screen name value will remain set on the tracker and sent with
// hits until it is set to a new value or to nil.
[tracker set:kGAIScreenName value:@"Home Screen"];

[tracker send:[[GAIDictionaryBuilder createAppView] build]];


イベントのトラッキング

// May return nil if a tracker has not already been initialized with a property
// ID.
id<GAITracker> = [[GAI sharedInstance] defaultTracker];

[tracker send:[[GAIDictionaryBuilder createEventWithCategory:@"ui_action"     // Event category (required)
                                                      action:@"button_press"  // Event action (required)
                                                       label:@"play"          // Event label
                                                       value:nil] build]];    // Event value

アラート表示

アラート

UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil
    message:@"タイトル"  //タイトル
    delegate:self  //デリゲートを自分自身に
    cancelButtonTitle:nil  //キャンセルボタン
    otherButtonTitles:@"OK", nil];  //確認ボタン
[alertView show];
[alertView release];

コンファーム

UIAlertView* confirmView =
[[[UIAlertView alloc] initWithTitle: @"ログインしていません"
                            message: @"ログインしますか"
                           delegate: self
                  cancelButtonTitle: @"いいえ"
                  otherButtonTitles: @"はい", nil] autorelease];
[confirmView show];


- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    if (buttonIndex==[alertView cancelButtonIndex]) {
        //キャンセルボタン
        return;
    }
    //キャンセル以外の処理
}

2013年10月11日金曜日

GameCenter



事前準備

iTunesConnectでアプリを登録し、GameCenterを有効にする


Info.plistの設定

Required device capabilitiesに「gamekit Boolean YES」を追加


認証

// GameCenter認証
[[GKLocalPlayer localPlayer] authenticateWithCompletionHandler:^(NSError *error) {
    if (error != nil) {
        //エラー処理
    }
}];

GKLeaderboardViewControllerDelegateプロトコル適用

//ヘッダーファイルにプロトコル追加
@interface TestLayer : CCLayer <GKLeaderboardViewControllerDelegate>


得点を送信

//iTunesConnectで設定したリーダーボードIDを設定
GKScore *scoreReporter = [[[GKScore alloc] initWithCategory:@"Leaderboard ID"] autorelease];
scoreReporter.value = HiScore;
[scoreReporter reportScoreWithCompletionHandler:^(NSError *error) {
    if (error != nil) {
        //エラー処理
    }
}];


リーダーボードの表示

GKLeaderboardViewController *lbController = [[GKLeaderboardViewController alloc] init];
if (lbController != nil) {
    lbController.leaderboardDelegate = self;
    [[CCDirector sharedDirector] presentModalViewController:lbController animated:YES];
}

//リーダーボードを抜ける時の処理
- (void)leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController {
    [[CCDirector sharedDirector] dismissViewControllerAnimated:YES completion:^{
        //
    }];
}

2013年10月7日月曜日

乱数

//シード
srandom(time(0));
//0-9を取得
int num = CCRANDOM_0_1() * 10;

2013年10月3日木曜日

ノードの削除

自分自身を削除

//YESでアクションやスケジュールもクリーンアップ
[self removeFromParentAndCleanup:YES];
//removeFromParentAndCleanup:YESと同じ
[self removeFromParent]


親ノードから削除

[self removeChildByTag:101]

2013年10月2日水曜日

CGPointの演算

//加算 (c1.x+c2.x,c1.y+c2.y)
ccpAdd(c1, c2);

//減算 (c1.x-c2.x,c1.y-c2.y)
ccpSub(c1, c2);

ベジェ曲線での移動

ccBezierConfig bezConf;
bezConf.controlPoint_1 = ccp(0, 0);
bezConf.controlPoint_2 = ccp(30, 0);
bezConf.endPosition = ccp(30, 10);
id move = [CCBezierBy actionWithDuration:1.0 bezier:bezConf];
[self runAction:move];

2013年10月1日火曜日

Parse issue: Unknown type name 'ClassName'

ビルドが通らず表題のメッセージが出る場合、import文の循環参照が疑わしい


.hファイル

#import "class.h" を @class class に書き換え

.mファイル

#import "class.h" を加える

時間調整のアクション

//時間調整
id delay = [CCDelayTime actionWithDuration:1.0];
CCSequence* seq = [CCSequence actions:delay, action ,nil];
[self runAction:seq];

座標の絶対値、相対値変換

スプライトからの相対値(ローカル座標)を、画面上の絶対座標(ワールド座標)に変換

//絶対値→相対値
CGPoint local = [sprite convertToNodeSpace:ccp(x, y)];

//相対値→絶対値
CGPoint world = [sprite convertToWorldSpace:ccp(x, y)];