2013年6月21日金曜日

バックグラウンドで動かす


AppDelegate.h

@interface AppDelegate : UIResponder <UIApplicationDelegate>
{
    UIBackgroundTaskIdentifier bgTask;
}

AppDelegate.m

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
        [application endBackgroundTask:bgTask];
    }];
}

以上でアプリがバックグランドに回っても動作し続けるが、10分までという制限がある。

しかし音声を再生したり、GPSを使っている場合は、イベントによって再度動かせる。

例えばGPSを使ってロケーションを取得していれば、ロケーションが変わったときに
ふたたび動き出す。

GPSをバックグランドで使うには、info.plistの編集が必要。

Information Property List の右の+をクリックして、Required background modesを選び、
item0のValueで、App registers for location updates を選ぶ。


2013年5月17日金曜日

FMDBによるデータベース検索


FMDBによるデータベース検索

NSURL *dirPath;
FMDatabase *db;
NSURL *dbPath;



    //Open DB
    dbPath = [dirPath URLByAppendingPathComponent:@"cdb.db"];
    db = [FMDatabase databaseWithPath:[dbPath absoluteString]];
    [db open];

    //Read all
    FMResultSet *rs = [db executeQuery:@"select * from cdb"];
                    
    while ([rs next]){
       ContId[j] = [rs stringForColumn:@"ContId"];
       CateId[j] = [rs stringForColumn:@"CateId"];
       title[j]  = [rs stringForColumn:@"Title"];
       imageFile[j] = [rs stringForColumn:@"ImageFile"];
       detail1[j] = [rs stringForColumn:@"Detail1"];
                        
       j++;
    }
    [rs close];
    [db close];


特定の項目検索の場合

    FMResultSet *rs = [db executeQuery:@"select * from cdb where CateId = ?", cid];



特定のワードを含む検索の場合
   //検索ワード
    NSString *srchtxt = [[NSString alloc]init] ;
    srchtxt = [srchtxt stringByAppendingString:@"%%"];
    srchtxt = [srchtxt stringByAppendingString:srchtext.text];
    srchtxt = [srchtxt stringByAppendingString:@"%%"];
    FMResultSet *rs = [db executeQuery:@"select * from cdb where Title like ?", srchtxt];


データベースの作成
    //Create DB
    dbPath = [dirPath URLByAppendingPathComponent:@"cdb.db"];
    db = [FMDatabase databaseWithPath:[dbPath absoluteString]];
    [db open];
    [db beginTransaction];

    [db executeUpdate:@"delete from cdb"];
    [db executeUpdate:@"create table cdb (ContId text, CateId text, Title text, ImageFile text, Detail1 text)"];
    [db commit];

データベース書き込み
    //Insert DB
    [db beginTransaction];
    [db executeUpdate:@"insert into cdb (ContId,CateId,Title,ImageFile,Detail1) values (?,?,?,?,?)",ContId,CateId,Title,ImageFile,Detail1];
     [db commit];




2013年4月25日木曜日

PopUp Viewのサイズ指定


PopUp Viewの大きさは、UIViewのほうに記述する。
PopUp Viewに記述しても効かない。

    if (setPop != nil)
    {
        [setPop dismissPopoverAnimated:YES];
    }
    UIViewController *vc = [[UIViewController alloc] init] ;
    vc.view.frame = CGRectMake(0, 0, 300, 500);
    vc.contentSizeForViewInPopover = vc.view.frame.size;
    
    setPop = [[UIPopoverController alloc] initWithContentViewController:vc];
    [setPop presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];

Print Menu表示(HTMLテキスト)


HTMLテキストを印刷する

    UIPrintInteractionController *pic = [UIPrintInteractionController sharedPrintController];
    pic.delegate = self;
    UIPrintInfo *printInfo = [UIPrintInfo printInfo];
    printInfo.outputType = UIPrintInfoOutputGeneral;
    printInfo.jobName = @"document"; //self.documentName;
    pic.printInfo = printInfo;
    UIMarkupTextPrintFormatter *htmlFormatter = [[UIMarkupTextPrintFormatter alloc]initWithMarkupText:@"<html><body>samaple HTML</body></html>"]; //self.htmlString];
    htmlFormatter.startPage = 0;
    htmlFormatter.contentInsets = UIEdgeInsetsMake(72.0, 72.0, 72.0, 72.0); // 1インチの余白
    pic.printFormatter = htmlFormatter;
    pic.showsPageRange = YES;
    
    void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) =^(UIPrintInteractionController *pic, BOOL completed, NSError *error) {
        if (!completed && error) {
            NSLog(@"Printing could not complete because of error: %@", error);
        }
    };
    
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        [pic presentFromBarButtonItem:sender animated:YES completionHandler:completionHandler];
        
    } else {
        [pic presentAnimated:YES completionHandler:completionHandler];
    }

 アプリケーションメニューの表示

外部アプリケーションのメニュ=を表示し、ファイルをアプリに送る


UIDocumentInteractionControllerは、iOS4から使えるが、facebook,twitter,Printなどは出てこない。
iOS6なら、UIActivityViewControllerを使う方よい。

ここでは、UIDocumentInteractionControllerのサンプルを載せる。




UIDocumentInteractionController *docInterCon;



    //データへのURL
    NSBundle *bundle = [NSBundle mainBundle];
    NSString *dataFilePath = [bundle pathForResource:@"file" ofType:@".text"];
    NSURL *url = [NSURL fileURLWithPath:dataFilePath];
    
    //
    self.docInterCon = [UIDocumentInteractionController interactionControllerWithURL:url];
    self.docInterCon.delegate = self;
        
    //アプリケーションのメニューを表示
    BOOL isValid;
    isValid = [self.docInterCon presentOptionsMenuFromBarButtonItem:_barbtn animated:YES];
    if (!isValid){
        NSLog(@"アプリケーションがありません");
    }

2013年4月18日木曜日

ローカルにファイル保存


    //Get Directory path
    NSString *bundleID = [[NSBundle mainBundle] bundleIdentifier];
    NSFileManager *fm = [NSFileManager defaultManager];
    NSURL *dirPath = nil;
    
    NSArray *appSupportDir = [fm URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask];
    
    if ([appSupportDir count ] >0)
    {
        dirPath= [[appSupportDir objectAtIndex:0]URLByAppendingPathComponent:bundleID];
        NSError *theErr = nil;
        if (![fm createDirectoryAtURL:dirPath withIntermediateDirectories:YES attributes:nil error:&theErr])
        {
            //error process
        }
    }
    
    //Write
    dirPath = [dirPath URLByAppendingPathComponent:@"aaa.txt"];
    
    BOOL result = [str writeToURL:dirPath atomically:YES encoding:NSUTF8StringEncoding error:&err];
    
    if (result) NSLog(@"Success write");
    
    //Read
    NSString *str1 = [NSString stringWithContentsOfURL:dirPath encoding:NSUTF8StringEncoding error:&err];
    
    NSLog(@"Read: %@",str1);

画像ファイルとテキストファイルをダウンロードして保存

ネットワーク経由で画像ファイルとテキストファイルをダウンロードして保存する


NSString *urlstring;
NSURL *url;
NSError *err = nil;
NSURL *path;

//serverIp1 サーバーのURL (http://xxxx.jp/xxxx/)
//dirPath  保存先のURL
//imageFile 画像ファイル名
//textFile テキストファイル名

//Download ImageFile
urlstring = [serverIp1 stringByAppendingString:imageFile];

url = [NSURL URLWithString:urlstring];

NSData *data = [NSData dataWithContentsOfURL:url options:nil error:&err];

//Write
path = [dirPath URLByAppendingPathComponent:ImageFile];

BOOL result = [data writeToURL:path options:NSDataWritingAtomic error:&err];
if (result == NO) break;

//Download Text file
urlstring = [serverIp1 stringByAppendingString:textFile];

url = [NSURL URLWithString:urlstring];

NSString *str = [NSString stringWithContentsOfURL:url encoding:NSShiftJISStringEncoding error:&err];

//Write
path = [dirPath URLByAppendingPathComponent:textFile];

result = [str writeToURL:path atomically:YES encoding:NSUTF8StringEncoding error:&err];
if (result == NO) break;

HTTP同期通信

通信時間が許されれば、同期通信のほうがプログラムは簡単。
レスポンスを処理したいときにも同期の方が便利。

textをPOSTし 、レスポンスをcontentsに。

NSURL *url = [NSURL URLWithString:urlstr];

NSData *myRequestData = [text dataUsingEncoding:NSUTF8StringEncoding];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: url];
[request setHTTPMethod: @"POST"];
[request setValue:@"text/html; charset=utf-8"  forHTTPHeaderField:@"content-type"];
[request setHTTPBody: myRequestData];

result = NULL;
contents = NULL;

//同期通信
NSURLResponse *resp;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&resp error:nil];
//convert to UTF8 text
contents = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

ApplicationSupportDirectoryのパスを得る

ApplicationSupportDirectoryのパスを得る
アプリ内でファイルを保存する場所として使う。


//Get Directory path
NSString *bundleID = [[NSBundle mainBundle] bundleIdentifier];
NSFileManager *fm = [NSFileManager defaultManager];
dirPath = nil;

NSArray *appSupportDir = [fm URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask];

if ([appSupportDir count ] >0)
{
    dirPath= [[appSupportDir objectAtIndex:0]URLByAppendingPathComponent:bundleID];
    NSError *theErr = nil;
    if (![fm createDirectoryAtURL:dirPath withIntermediateDirectories:YES attributes:nil error:&theErr])
    {
        dirPath = nil;
    }
}

プログラムからViewの移動

プログラム中からViewを移動(遷移)させたいとき

stroyboardを使ったviewへ移動するとき


#import "View1.h"

    View1 *vc1;
    vc1 = [self.storyboard instantiateViewControllerWithIdentifier:@"view1"];
    [self presentViewController:vc1 animated:YES completion:nil];


Identifier (@"view2")は、storyboardで、storyboard IDとして入力しておくこと。


xibファイルがあるとき

#import "View2.h"


    View2 *vc1 = [[View2 alloc]initWithNibName:@"View2" bundle:[NSBundle mainBundle]]  ;
    [self presentViewController:vc1 animated:YES completion:nil];


NIbNameは、xibファイル名


戻る場合


    [self dismissViewControllerAnimated:YES completion:nil];



Navigation Controllerを使っている場合

[[self navigationController] pushViewController:vc1 animated:YES];


1つ上の階層へ戻る
[self.navigationController popViewControllerAnimated:YES];


2013年2月8日金曜日

AlertViewを自動で閉じる

AlertViewにボタンを表示せずに、メッセージを表示して一定時間後に自動的に閉じる。


-(void)okOrder:(UIButton*)btn
{
    UIAlertView *alt = [[UIAlertView alloc]initWithTitle:@"" message:@"注文を受け付けました" delegate:self cancelButtonTitle:nil otherButtonTitles:nil, nil];
    //Timer 設定
    [NSTimer scheduledTimerWithTimeInterval:2.0f target:self selector:@selector(performDismiss:) userInfo:alt repeats:NO];

    [alt show];
}

//Timer終了でアラートを閉じる
-(void)performDismiss:(NSTimer*)timer
{
    UIAlertView *alt = [timer userInfo];
    [alt dismissWithClickedButtonIndex:0 animated:NO];
}

2013年2月7日木曜日

Table にメニューを追加


#pragma UIMenuControllor

-(BOOL)canPerformAction:(SEL)action withSender:(id)sender{

    if (action == @selector(delete:)) return YES;
    if (action == @selector(change:)) return YES;
    
    return NO; //標準のメニュー項目は無効にする
}
//For menuContorollor
-(BOOL)canBecomeFirstResponder{
    return YES;
}
//Table Selected
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    //選択されたセルの下にメニューを表示
   //セルの高さは100、幅は240
    int point = (indexPath.row+1)*100-20;
    [self.tableView becomeFirstResponder];
    UIMenuController *menuCont = [UIMenuController sharedMenuController];
    [menuCont setTargetRect:CGRectMake(120, point, 0, 0) inView:self.tableView];
    menuCont.arrowDirection = UIMenuControllerArrowUp;
    
    NSMutableArray *menuItem = [NSMutableArray array];
    [menuItem addObject:[[UIMenuItem alloc]initWithTitle:@"削除"
                                                  action:@selector(delete:)]];
    [menuItem addObject:[[UIMenuItem alloc]initWithTitle:@"変更"
                                                  action:@selector(change:)]];
    menuCont.menuItems = menuItem;
    [menuCont setMenuVisible:YES animated:YES];
}
//削除
-(void)delete:(id)sender
{
    NSLog(@"menu:%@", sender);
    
}
//変更
- (void)change:(id)sender
{
    
}

2013年2月6日水曜日

Custom Table Cellの作り方

New File/User Interface/Emptyを選び、CustomCell.xib
を作る。

CustomCell.xibをクリックしてStoryBoardで画面作成
   TableViewCellをドラッグ
   サイズをTableに合わせる
   その上にパーツ(ラベル、テキスト、イメージ等)を載せる

NewFileで、CustomCell.h,CustomCell.m作成

//  CustomCell.h
#import <UIKit/UIKit.h>
@interface CustomCell: UITableViewCell{
}
@end

CustomCell.xibをクリック、StoryBoard
   Custom ClassをCustomCellに設定
   IdentifierにCell名設定
   Delegate, Datasourceリンク

 .hにIBOUTlet設定


//  CustomCell.h
#import <UIKit/UIKit.h>

@interface CustomCell: UITableViewCell{
    
}
@property (nonatomic,retain)IBOutlet UILabel *nameLabel;
@property (nonatomic,retain)IBOutlet UILabel *priceLabel;
@property (nonatomic,retain)IBOutlet UILabel *priceGLabel;
@property (nonatomic,retain)IBOutlet UILabel *countLabel;
@property (nonatomic,retain)IBOutlet UIImageView *image;
@property (nonatomic,retain)IBOutlet UIButton *countBtn;

@end

//  CustomCell.m
#import <UIKit/UIKit.h>
#include "CustomCell.h"
@implementation CustomCell
@synthesize nameLabel;
@synthesize priceLabel;
@synthesize priceGLabel;
@synthesize countLabel;
@synthesize image;
@synthesize countBtn;
@end

メインの.mファイルでCustom Cell設定

#import "CustomCell.h"
NSMutableArray *_objects;

#define CUSTOM_CELL_NIB @"CustomCell"
float cellheight_;

- (void)viewDidLoad
{
    [super viewDidLoad];
    //Table delegate
    self.tableView.delegate = self;
    //Table data
    _objects = [[NSMutableArray alloc] initWithObjects:
                @"tabel1",@"table2", nil];
    
    //Table Cell Height
    UINib* nib = [UINib nibWithNibName:CUSTOM_CELL_NIB bundle:nil];
    NSArray* array = [nib instantiateWithOwner:nil options:nil];
    CustomCell* cell = [array objectAtIndex:0];
    cellheight_ =cell.frame.size.height;

}

#pragma mark - Table View

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return cellheight_;
}

//Table section
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

//Table row
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
     return _objects.count;
}

//Init Table Data
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:CUSTOM_CELL_NIB];
    
    if (cell ==nil){
        UINib* nib = [UINib nibWithNibName:CUSTOM_CELL_NIB bundle:nil];
        NSArray* array = [nib instantiateWithOwner:nil options:nil];
        cell = [array objectAtIndex:0];
    }
    
    NSDate *object = _objects[indexPath.row];
    //cell.textLabel.text = [object description];
    cell.nameLabel.text = [object description];
    
    return cell;
}

//ボタンがタップされたらテーブルに追加する
- (void)insert:(UIButton*)btn
{
    [_objects insertObject:@"hogehoge" atIndex:0];
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}


2013年2月5日火曜日

TableView Basic

TableView ラベルのみ

Storyboard
    TableView Style = basic ラベルのみの場合
    Delegate, DataSouce 設定
    Cell Identifier = Cell 入力


NSMutableArray *_objects;

- (void)viewDidLoad
{
    [super viewDidLoad];

    //Table delegate
    self.tableView.delegate = self;
    //Table data
    _objects = [[NSMutableArray alloc] initWithObjects:
                @"tabel1",@"table2", nil];

}

#pragma mark - Table View

//Table section
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

//Table row
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
     return _objects.count;
}

//Init Table Data
//セルにデータを設定する処理
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
    
    NSDate *object = _objects[indexPath.row];
    cell.textLabel.text = [object description];
    
    return cell;
}

リストがタップされたときの処理は以下の中に書く

//リストがタップされた
//iPadのとき
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
 if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {

 }
}
//iPhoneのとき
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{

}


//ボタンがタップされたらテーブルに追加する
//1行追加され、cellForRowAtIndexPathが呼ばれる
- (void)insert:(UIButton*)btn
{
    [_objects insertObject:@"hogehoge" atIndex:0];
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}

//1行削除
//selectedRow行が削除され

    //Update Table
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:selectedRow inSection:0];
    [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];


//データ変更
//reloadDataでcellForRowAtIndexPathが呼ばれる

    //Update Table
    [self.tableView reloadData];


2013年1月30日水曜日

複数のボタンを同じメソッドで見分ける


複数のボタンを同じメソッドで作成する。
そのとき、識別番号(index)を渡し、Buttonのtagに設定する。

    [self thumBtn :0:@"darkr.png":71 :77 :150:172];
    [self thumBtn :1:@"batb.png"  :379:77 :120:82];
    [self thumBtn :2:@"dark.png"  :379:166:120:82];
    [self thumBtn :3:@"mada.png"  :71 :260:172:130];
    [self thumBtn :4:@"neo.png"   :353:260:174:130];

ボタン生成メソッド

-(void)thumBtn:(int)index: (NSString*)file: (int)x :(int)y :(int)w :(int)h
{
    UIImage *img = [UIImage imageNamed:file];
    UIButton *btn =[UIButton buttonWithType:UIButtonTypeRoundedRect];
    btn.frame = CGRectMake(x,y,w,h);
    [btn setBackgroundImage:img forState:UIControlStateNormal];
    [btn addTarget:self action:@selector(playMovie:) forControlEvents:UIControlEventTouchDown];
    btn.tag = index; //ボタン識別用
    [imageView addSubview:btn];
}


-(void)playMovie:(UIButton*)btn{
    
    int index = btn.tag; //押されたボタンを識別する
    NSLog(@"Button:%d", index);
}

2013年1月28日月曜日

AdHoc設定

AdHoc設定

iOS Provisioning Portal siteを開く
Cetificates/Distributionタブで配布用証明書作成
デバイス追加の必要があれば、Devicesで追加(UUID必要)
Provisioning/DistributionタブでNew Profileで作成
MacにCertificates,Profileをダウンロード
Cerificatesをダブルクリック
システムにドラッグ
AdHoc Profileをダブルクリック
リフレッシュ

配布するipaをビルドする

product/Edit SchemeでArchiveがReleaseになっていること
Product/Archive、Distribute,Save for ...Ad-Hocでipaファイルを保存