CSVファイルの読み込み(配列格納)

CSVからデータを読みだして配列に格納する方法。

    // CSVファイルからセクションデータを取得する
    NSString *csvFile = [[NSBundle mainBundle] pathForResource:@"CSVファイル名(拡張子なし)" ofType:@"csv"];
    NSData *csvData = [NSData dataWithContentsOfFile:csvFile];
    NSString *csv = [[NSString alloc] initWithData:csvData encoding:NSUTF8StringEncoding];
    NSScanner *scanner = [NSScanner scannerWithString:csv];
    
    // 改行文字の集合を取得
    NSCharacterSet *chSet = [NSCharacterSet newlineCharacterSet];
    // 一行ずつの読み込み
    NSString *line;
    arrDetail = [[NSMutableArray alloc] init];

    //タイトル行読み飛ばしフラグ。読み込む場合はtrueにする
    bool titleUse = false; 
    while (![scanner isAtEnd]) {
        // 一行読み込み
        [scanner scanUpToCharactersFromSet:chSet intoString:&line];
        if(titleUse){
            // カンマ「,」で区切る
            NSArray *array = [line componentsSeparatedByString:@","];
            // 配列に挿入する
            [arrDetail addObject:array];
        }
        // 改行文字をスキップ
        [scanner scanCharactersFromSet:chSet intoString:NULL];
        titleUse = true;
    }

 
 
参考にさせていただいたサイト様
 http://b.ruyaka.com/2010/10/17/iphoneアプリ開発-csvファイルデータ取得/

マップの呼び出しとルート設定

自分のアプリ内からルートを設定したGoogleMapを呼び出す方法。
(標準のマップアプリではなく、safari上でGoogleMapを呼び出す方法)

追記:
iPhoneシミュレータ上ではsafariが起動しますが、実機だと標準のマップアプリで起動する模様。

 

            NSString *place = @"daddr=目的地&saddr=現在地";
            NSString *placeEscape = [place stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
            NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://maps.google.com/maps?%@", placeEscape]];
            [[UIApplication sharedApplication] openURL:url];            

 
参考にさせていただいたサイト様
 http://634.ayumu-baby.com/uiapplication_openurl.html
 http://ushigyu.net/2011/12/08/1tap_root_search/

TableViewのタップ制御

TableViewで、データの表示をしたいだけで、特にタップ時のアクションなどを起こしたくない場合の設定。

- (void)viewDidLoad
{
    //タップ時のハイライトをOFF
    self.tableView.allowsSelection = NO;
    [super viewDidLoad];
}

//タップ時のアクションをコメントアウト
//- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
//{
//}

 
 
特定のセルだけタップを可能にして、他のセルのタップアクションはOFFにする場合の設定。
※例は、セクション0のセルはタップ可能、それ以外はタップ不可

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        //cellの作成時に、タップさせたいセルとそうじゃないセルを切り分け
        if (indexPath.section == 0) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        }else {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:CellIdentifier];
            //セル単位でタップ時のハイライトをOFF
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
        }
    }
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    //タップ時のアクションで、ハイライトを設定したセルを切り分け
    if (indexPath.section == 0){
        if (indexPath.row == 0) {
            //セクション0ロウ0の処理;
        }
    }
}

アプリ内からメールを送信

アプリ内からiPhone標準のメール機能を呼び出して、メールを送信する方法のまとめ。

『前準備』
・アプリにフレームワーク『MessageUI.framework』を追加
 

『メール機能を使用する.hで、フレームワークを呼び出す』

#import <MessageUI/MessageUI.h>  
#import <MessageUI/MFMailComposeViewController.h>

@interface DetailViewController : UITableViewController<MFMailComposeViewControllerDelegate>

 

『メール機能を使用する.m内に処理を構築』

- (void)sendMail
{
    Class mailClass = (NSClassFromString(@"MFMailComposeViewController"));
    if (mailClass != nil){
        //メールが送信できる状態か確認
        if ([mailClass canSendMail]){
            [self showComposerSheet];
        } else {
            [self showAlert:@"メールが起動出来ません":@"この機能は、メールの設定後にご使用下さい。"];
        }
    }
}

-(void) showComposerSheet {
	MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
	picker.mailComposeDelegate = self;
    
	[picker setSubject:@"メール件名"];
    
	NSString *emailBody = @"メール本文\nメール本文2";
	[picker setMessageBody:emailBody isHTML:NO];
    
	[self presentModalViewController:picker animated:YES];
}

- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {
	switch (result){
		case MFMailComposeResultCancelled:
			//キャンセルした場合
			break;
		case MFMailComposeResultSaved:
			//保存した場合
			break;
		case MFMailComposeResultSent:
			//送信した場合
			break;
		case MFMailComposeResultFailed:
			[self showAlert:@"メール送信失敗":@"メールの送信に失敗しました。ネットワークの設定などを確認して下さい"];
			break;
		default:
			break;
	}
	[self dismissModalViewControllerAnimated:YES];
}

-(void)showAlert:(NSString*)alertMsgTitle:(NSString*)alertMsg{
    UIAlertView *alert = [[UIAlertView alloc] init];
    alert.title = alertMsgTitle;
    alert.message = alertMsg;
    [alert addButtonWithTitle:@"OK"];
    [alert show];
}

※showAlertは、オマケです。

上記を記述後、『sendMail』を好きなタイミングで呼び出せば、メール送信の画面がアプリ内に展開されます。

nib but the view outlet was not set

簡単な画面遷移のプログラムを組んでいた時に、急にSIGABRTを連発して先に進まなくなり、エラーの詳細を確認したら『(前略)nib but the view outlet was not set』となっていて、このエラーメッセージでググったら、新しく作ったViewがFile’s Ownerにリンクされてないだけということが判明した。

画面を作るのと一緒に、前画面から次画面にデータを受け渡す処理を構築していたせいで、そのデータの受け渡しや利用の仕方に問題があるものと思い込んで、数十分、あーでもないこーでもないと時間を無駄にした。
 
 
超基本的なことでも、タイミングが悪いと強敵になるという話。
あと、横着せずにエラーメッセージはちゃんと確認しようね、という話。