Browsing articles in "iPhone"
7月
6
2010

“The program being debugged is not being run”と表示されてXCodeで実機テスト中のiPhoneアプリが落ちる

XCodeでiPhoneの実機テストをしようとすると、アプリの起動画面が表示されるがすぐ落ちて、XCodeのエラーメッセージには「The program being debugged is not being run」と表示されることがあります。

これには、以下のような原因が考えられます。

構成が Debug 以外になっている
プロビジョニングファイルの期限が切れている

laiso – iPhoneアプリ開発グループより引用。

その他にも違うバージョンのアプリがすでに入っている場合にも同じようなことが起きます。

参考リンク

  1. Q: Xcodeビルドして実機デバッギはじめると "The program being debugged is not being run." とかでて即終了してしまうよ! – laiso – iPhoneアプリ開発グループ
  2. Error from Debugger: The program being debugged is not being run. – iPhone Dev SDK Forum
7月
3
2010

iPhoneアプリのテンプレートを作ってみる

XCodeでiPhone OSの新規プロジェクトを作るとき、いつもxibファイルを抹消する作業から始めるのが煩いので、抹消済みのテンプレートがほしい!と思ったので作ってみました。

そんなわけで、iPhoneアプリのテンプレートの作り方。

ちなみに、完成予想図は以下の通り。

まずはそれぞれの場所

ベースとなるiPhone OSのテンプレート

/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Project Templates/Application

ベースとなるMac OS Xのテンプレート

/Developer/Library/Xcode/Project Templates

今回作るユーザーテンプレートの保存場所

/Library/Application Support/Developer/Shared/Xcode/Project Templates

作り方

XCodeはiPhone OSという名称を貫き通す感じだと思いますが、せっかくなのでフォルダ名をiOSとしてみます。
以下のコマンドで出来上がります。
今回は、iPhone OSのView-based Applicationをベースにしました。

% cd /Library/Application\ Support/Developer/Shared/Xcode/Project\ Templates
% mkdir iOS
% cd iOS
% sudo cp -R /Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Project\ Templates/Application/View-based\ Application ./

あとは、自分の思うがままにいじりまくったらOKです!

参考リンク

  1. xcodeでテンプレート – tsurushuuの日記
  2. Xcodeのテンプレートを作成 – griffin-stewieの日記
7月
2
2010

Objective-Cで二次元配列を扱う

クラスのプロパティに二次元配列を持たせます。
ここでは、メモリを動的に確保する方向でいきます(そんなわけで、実際はただのポインタのポインタ)。

ArrayClass.h

@interface ArrayClass : NSObject {
  char **array;
}

@property (nonatomic) char **array;

@end

ArrayClass.m

@implementation ArrayClass

@synthesize array;

-(id)init {
  self = [super init];

  if (self) {
    array = (char**)malloc(sizeof(char*)*10);
    for (int i = 0; i < 10; i++) {
      array[i] = (char*)malloc(sizeof(char)*15);
    }
  }

  return self;
}

-(void)dealloc {
  for (int i = 0 ; i < 10; i++) {
    free(array[i]);
  }
  free(array);
  [super dealloc];
}

@end

こうすることで、

ArrayClass *obj = [[[ArrayClass alloc] init] autorelease];
obj.array[0][1] = 1;

のように扱うことができます。

参考リンク

  1. Dynamic allocation of two dimensional array by C
4月
30
2010

iPhoneアプリにAdMob広告を追加する方法

ここでは、プログラム的に追加する(Interface Builderを一切使わない)方法を説明します。

こちらの環境は以下の通りです。

Mac OS X 10.6.3
Xcode 3.2.2
iPhoneシミュレータ 3.1.3

プロジェクトのセットアップ

Xcodeで、プロジェクトを作成します(View-based Applicationを選択)。

プロジェクト名は、「AdMob」としました。

Frameworksグループを右クリックして[追加] -> [既存のフレームワーク]で、以下のフレームワークを追加します。

  • AudioToolbox.framework
  • QuartzCore.framework
  • MediaPlayer.framework
  • MessageUI.framework

続いて、AdMobのサイトでダウンロードしてきたiPhone用のAdMobのSDKに含まれている以下の二つをプロジェクトに追加します(FinderからXcodeプロジェクトにドラッグアンドドロップで追加できます)。

  • AdMob
  • TouchJSON

このとき、「デスティネーショングループのフォルダに項目をコピーする(必要な場合)」にチェックが入っていることを確認し、[追加]を選択します。

InterFace Builderを使わないための設定

Resourceの中にある以下の2ファイルを削除します。

  • AdMobViewController.xib
  • MainWindow.nib

そして、Admob-info.plistの中の「Main nib file base name」という行を削除します。

続いて、Other Sources/main.mを以下のように書きかえます。

int retVal = UIApplicationMain(argc, argv, nil, nil);
int retVal = UIApplicationMain(argc, argv, nil, @"AdMobAppDelegate");

そして、Classes/AdMobAppDelegate.mを以下のように書きかえます。

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

  // Override point for customization after app launch
  [window addSubview:viewController.view];
  [window makeKeyAndVisible];

  return YES;
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  CGRect frame = [[UIScreen mainScreen] bounds];
  window = [[UIWindow alloc] initWithFrame:frame];

  viewController = [[AdMobViewController alloc] init];

  // Override point for customization after app launch
  [window addSubview:viewController.view];
  [window makeKeyAndVisible];

  return YES;
}

実装

実際にAdMobを組み込む処理を追加します。AdMobのSDKに含まれているサンプルを参考にしました。

Classes/AdMobViewController.h

#define AD_REFRESH_PERIOD 12.5 // display fresh ads every 12.5 seconds

#import <UIKit/UIKit.h>
#import "AdMobView.h"
#import "AdMobAppDelegate.h"
#import "AdMobDelegateProtocol.h"

@interface AdMobViewController : UIViewController<AdMobDelegate> {
  AdMobView *adMobAd;
  NSTimer *refreshTimer;
}

@end

Classes/AdMobViewController.m

#import "AdMobViewController.h"

@implementation AdMobViewController

/*
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
  if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
    // Custom initialization
  }
  return self;
}
*/

// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
  // get the window frame here.
  CGRect appFrame = [UIScreen mainScreen].applicationFrame;

  UIView *view = [[UIView alloc] initWithFrame:appFrame];
  // making flexible because this will end up in a navigation controller.
  view.autoresizingMask = UIViewAutoresizingFlexibleHeight;
  self.view = view;

  [view release];

  // Request an ad
  adMobAd = [AdMobView requestAdWithDelegate:self]; // start a new ad request
  [adMobAd retain]; // this will be released when it loads (or fails to load)
}

- (NSString *)publisherId {
  return @"a14bd9a27f5f572"; // this should be prefilled; if not, get it from www.admob.com
}

- (UIViewController *)currentViewController {
  return self;
}

/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
  [super viewDidLoad];
}
*/

/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
  // Return YES for supported orientations
  return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/

- (void)didReceiveMemoryWarning {
  // Releases the view if it doesn't have a superview.
  [super didReceiveMemoryWarning];

  // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
  // Release any retained subviews of the main view.
  // e.g. self.myOutlet = nil;
}

- (void)didReceiveAd:(AdMobView *)adView {
  NSLog(@"AdMob: Did receive ad");
  // get the view frame
  CGRect frame = self.view.frame;

  // put the ad at the bottom of the screen
  adMobAd.frame = CGRectMake(0, frame.size.height - 48, frame.size.width, 48);

  [self.view addSubview:adMobAd];
  [refreshTimer invalidate];
  refreshTimer = [NSTimer scheduledTimerWithTimeInterval:AD_REFRESH_PERIOD target:self selector:@selector(refreshAd:) userInfo:nil repeats:YES];
}

- (void)refreshAd:(NSTimer *)timer {
  [adMobAd requestFreshAd];
}

// Sent when an ad request failed to load an ad
- (void)didFailToReceiveAd:(AdMobView *)adView {
  NSLog(@"AdMob: Did fail to receive ad");
  [adMobAd removeFromSuperview];  // Not necessary since never added to a view, but doesn't hurt and is good practice
  [adMobAd release];
  adMobAd = nil;
  // we could start a new ad request here, but in the interests of the user's battery life, let's not
}

- (void)dealloc {
  [super dealloc];
}

@end

いざ実行!

実行してみるとこんな感じになると思います。

下の方に広告が表示されていますね!


Now loading...

PR

Flickr