아이폰어플개발정보2010. 9. 15. 07:58
Easy To Create Buttons with Cocos2D

Those of you who use cocos2d a lot might understand why I created this class as some point. Hopefully it may save some of you those nasty 5 line blobs that you normally need to create a simple button. Usage is simple, just do:

[self addChild:[Button buttonWithText:@"back" atPosition:ccp(80, 50) target:self selector:@selector(back:)]]; [self addChild:[Button buttonWithImage:@"openFeint.png" atPosition:ccp(400, 50) target:self selector:@selector(openOpenFeint:)]];

You’ll need to create your own button.png and button_p.png (the second one is the image shown when you are touching the button). Also you’ll need to choose your own font. Here is the code…

// // Button.h // StickWars - Siege // // Created by EricH on 8/3/09. //   @interface Button : Menu { } + (id)buttonWithText:(NSString*)text atPosition:(CGPoint)position target:(id)target selector:(SEL)selector; + (id)buttonWithImage:(NSString*)file atPosition:(CGPoint)position target:(id)target selector:(SEL)selector; @end   @interface ButtonItem : MenuItem { Sprite *back; Sprite *backPressed; } + (id)buttonWithText:(NSString*)text target:(id)target selector:(SEL)selector; + (id)buttonWithImage:(NSString*)file target:(id)target selector:(SEL)selector; - (id)initWithText:(NSString*)text target:(id)target selector:(SEL)selector; - (id)initWithImage:(NSString*)file target:(id)target selector:(SEL)selector; @end
// // Button.m // StickWars - Siege // // Created by EricH on 8/3/09. //   #import "Button.h"     @implementation Button + (id)buttonWithText:(NSString*)text atPosition:(CGPoint)position target:(id)target selector:(SEL)selector { Menu *menu = [Menu menuWithItems:[ButtonItem buttonWithText:text target:target selector:selector], nil]; menu.position = position; return menu; }   + (id)buttonWithImage:(NSString*)file atPosition:(CGPoint)position target:(id)target selector:(SEL)selector { Menu *menu = [Menu menuWithItems:[ButtonItem buttonWithImage:file target:target selector:selector], nil]; menu.position = position; return menu; } @end   @implementation ButtonItem + (id)buttonWithText:(NSString*)text target:(id)target selector:(SEL)selector { return [[[self alloc] initWithText:text target:target selector:selector] autorelease]; }   + (id)buttonWithImage:(NSString*)file target:(id)target selector:(SEL)selector { return [[[self alloc] initWithImage:file target:target selector:selector] autorelease]; }   - (id)initWithText:(NSString*)text target:(id)target selector:(SEL)selector { if(self = [super initWithTarget:target selector:selector]) { back = [[Sprite spriteWithFile:@"button.png"] retain]; back.anchorPoint = ccp(0,0); backPressed = [[Sprite spriteWithFile:@"button_p.png"] retain]; backPressed.anchorPoint = ccp(0,0); [self addChild:back];   self.contentSize = back.contentSize;   Label* textLabel = [Label labelWithString:text fontName:@"take_out_the_garbage" fontSize:22]; textLabel.position = ccp(self.contentSize.width / 2, self.contentSize.height / 2); textLabel.anchorPoint = ccp(0.5, 0.3); [self addChild:textLabel z:1]; } return self; }   - (id)initWithImage:(NSString*)file target:(id)target selector:(SEL)selector { if(self = [super initWithTarget:target selector:selector]) {   back = [[Sprite spriteWithFile:@"button.png"] retain]; back.anchorPoint = ccp(0,0); backPressed = [[Sprite spriteWithFile:@"button_p.png"] retain]; backPressed.anchorPoint = ccp(0,0); [self addChild:back];   self.contentSize = back.contentSize;   Sprite* image = [Sprite spriteWithFile:file]; [self addChild:image z:1]; image.position = ccp(self.contentSize.width / 2, self.contentSize.height / 2); } return self; }   -(void) selected { [self removeChild:back cleanup:NO]; [self addChild:backPressed]; [super selected]; }   -(void) unselected { [self removeChild:backPressed cleanup:NO]; [self addChild:back]; [super unselected]; }   // this prevents double taps - (void)activate { [super activate]; [self setIsEnabled:NO]; [self schedule:@selector(resetButton:) interval:0.5]; }   - (void)resetButton:(ccTime)dt { [self unschedule:@selector(resetButton:)]; [self setIsEnabled:YES]; }   - (void)dealloc { [back release]; [backPressed release]; [super dealloc]; }   @end

A common question I see on the cocos2d forums is ‘when I want to make my game scroll, do I move the camera or the layer?’ or some variant of that. I also got some more detailed questions about how to make a functioning 2D scroller, so I’m going to described how I got it to work.

First of all, the answer to the above question is you move the layer. If you follow the examples in the cocos2d download, you have a “GameScene” and a “GameLayer”. Well, everything that needs to be moved when your game scrolls should be added as a child to that GameLayer. If you are using a TileMap as a background, this includes that tilemap. The only thing that you don’t add as a child to the GameLayer is stuff that does not move with the scrolling view, such as your HUDLayer that has text that shows your characters health. Other than that, your character, the background, other characters, should all be added to the GameLayer.

You have to remember which objects are absolute (attached to your GameScene or other layers) versus those that are relative (a child of your GameLayer) when you set up your touch handling code. For my HUD that has buttons you can press at any time, say to pause the game, you want to add the touch handling object to your GameScene or HUDLayer class, since it doesn’t move. But if you want to be able to touch objects that scroll along with your view in the game itself, your touch handling code needs to be in an object that is a child of your GameLayer.

This might be a little confusing, so let’s see some code:

gameLayer = [GameLayer node]; [gameScene addChild:gameLayer z:zOrder_GameLayer];   hudLayer = [HUDLayer node]; [gameScene addChild:hudLayer z:zOrder_HudLayer];   tileMap = [BGTileMap node]; [gameLayer addChild:tileMap z:-1];   [gameScene addChild:[PauseGameButton node] z:zOrder_GameButtons]; [gameLayer addChild:[FireGunAtTouchPoint node]];

The pause game button is always on your screen, while the point at which your character fires the gun depends on how how far your view has been scrolled (by moving GameLayer).

Let’s see some of the code that actually moves this game layer:

- (void)setViewpointCenter:(CGPoint)point { CGPoint centerPoint = ccp(240, 160); viewPoint = ccpSub(centerPoint, point);   // dont scroll so far so we see anywhere outside the visible map which would show up as black bars if(point.x < centerPoint.x) viewPoint.x = 0; if(point.y < centerPoint.y) viewPoint.y = 0;   // while zoomed out, don't adjust the viewpoint if(!isZoomedOut) gameLayer.position = viewPoint; }

When do you call that method? Well, it depends on what you want, but generally these scrolling games follow around the movement of your ‘main’ character, right? So whatever character the you want to follow, add this to override the standard CocosNode setPosition method so you update your viewpoint whenever the character moves

- (void)setPosition:(CGPoint)point { [[StandardGameController sharedSingleton] setViewpointCenter:point]; [super setPosition:point]; }

Note that the StandardGameController is a construct of mine that I use to separate the game logic out from the display code. It doesn’t matter exactly how you do it, you just need a way to have your main character object call back to something that contains a reference to GameLayer so it can adjust the position of your GameLayer.

Now remember, for your background to scroll properly, you need to add your background tileMap as a child of your GameLayer that is being moved around.

That being said, I found that an important method was missing from the cocos2d tilemap that I need to use in order to detect collisions based on the types of tiles encountered. I created a subclass of TMXTiledMap and added in these methods:

- (CGPoint)coordinatesAtPosition:(CGPoint)point { return ccp((int)(point.x / self.tileSize.width), (int)(self.mapSize.height - (point.y / self.tileSize.height))); }   - (unsigned int)getGIDAtPosition:(CGPoint)point { return [layer tileGIDAt:[self coordinatesAtPosition:point]]; }

That way it’s easy to figure out what tile any individual object is colliding with. For example, in my main character object I can have code that runs in step: function with this:

BGTileMap* tileMap = [StandardGameController sharedSingleton].tileMap; CGPoint coordinate = [tileMap coordinatesAtPosition:self.position]; BBLog(@"Right now on tile %d",[tileMap.layer tileGIDAt:coordinate]);

Now I know what type of tile I am overlapping, and I can respond to the environment accordingly.

This is really all the code that you need to make a scrolling game view…I think some people overthink it and try adjusting the position of every object individually with some offset, but it’s not necessary since your objects can use relative positions with their parent.

I have one last bit of code to add, and this is something kind of fun. It’s not complete, but at least it’s a start. What this allows you to do is ‘zoom out’ so you can see your entire map with ALL the objects shrunk down, and then zoom back in to your character. The only tricky part is when you zoom back in, you have to slowly adjust your viewpoint in steps so the zoom in action is centered on your character, instead of jumping at the end.

#define ZOOM_BACK_IN_INTERVALS 10 #define ZOOM_OUT_RATE 0.3 // TODO need to refine this so for each step it uses the new viewpoint - (void)setZoom:(BOOL)zoomedIn { BBLog(@"Zooming in %d", zoomedIn);   // this scales it out so the whole height of the tilemap is in the screen float zoomScaleFactor = 320 / (tileMap.mapSize.height * tileMap.tileSize.height); if(zoomedIn) { [gameLayer runAction:[ScaleTo actionWithDuration:ZOOM_OUT_RATE scale:1.0]]; [gameLayer runAction:[MoveTo actionWithDuration:ZOOM_OUT_RATE position:viewPoint]]; [self schedule:@selector(setZoomedBackIn:) interval:ZOOM_OUT_RATE]; // need this for the transistion } else { [gameLayer runAction:[ScaleTo actionWithDuration:ZOOM_OUT_RATE scale:zoomScaleFactor]]; [gameLayer runAction:[MoveTo actionWithDuration:ZOOM_OUT_RATE position:ccp(0,0)]]; isZoomedOut = YES; } }   // need this small correction at the end to account of the player is moving and the viewpoint has changed to avoid jitter #define ZOOM_OUT_CORRECTION_RATE 0.3 - (void)setZoomedBackIn:(ccTime)dt { [self unschedule:@selector(setZoomedBackIn:)]; [gameLayer runAction:[MoveTo actionWithDuration:ZOOM_OUT_CORRECTION_RATE position:viewPoint]]; [self schedule:@selector(setZoomedBackInFinished:) interval:ZOOM_OUT_CORRECTION_RATE]; // need this for the transistion }   - (void)setZoomedBackInFinished:(ccTime)dt { [self unschedule:@selector(setZoomedBackInFinished:)]; isZoomedOut = NO; }

Now you see why my viewPoint variable was a class member…you’ll need it for these methods to work.

The reason this code isn’t complete is when it starts zooming in, it creates the actions to zoom in on the current viewpoint, but if the player is moving by the time the zoom animation is done, that viewpoint is changed and needs to ’snap’ to the new viewpoint. That is the reason for the setZoomedBackIn: method, which really shouldn’t have to move the gameLayer anymore. However, I haven’t yet written the code to continuously create smaller move actions to take into account a moving viewpoint as the animation continues, but doing so shouldn’t be that hard. If you want to see that bit when I finish, post in the comments and I’ll add it in.

Posted by 오늘마감

댓글을 달아 주세요

아이폰어플개발정보2010. 9. 15. 07:58
Using Box2D Physics Engine with Cocos2D iPhone

Starting work on my new project, I’ve found Box2D to be a far superior physics engine than chipmunk. It is more mature, the API more flexible, and it seems to even perform faster. However, the cocos2d code for it was rather space, so here is a sort of helper file I had to create to make it work with my game.

Keep in mind this game is in progress and I’ve only been using this for a few days, so it may have issues that might pop up later on. It seems to be working very well for now though, with 40-50 objects on screen moving around with ~40 FPS.

Here is the header

// // Box2DEngine.h // // Created by EricH on 7/22/09. // Copyright 2009 __MyCompanyName__. All rights reserved. //   #import "Box2D.h"   // made this an extern constant to avoid obj c lookup overhead extern b2World *bb_world;   @interface Box2DEngine : CocosNode { }   + (Box2DEngine *)sharedSingleton; - (void)createWorld:(CGSize)size; - (void)deleteWorld; - (void)runSimulation; @end

The .mm file

// // Box2DEngine.mm // // Created by EricH on 7/22/09. // Copyright 2009 __MyCompanyName__. All rights reserved. //   #import "HookActor.h"     #import "Box2DEngine.h" #import "SuperBox2DActor.h"   b2World* bb_world;   const float32 timeStep = 1.0f / 60.0f; const int32 velocityIterations = 10; const int32 positionIterations = 10;   #define MAX_NUM_COLLISIONS 2048 // TODO make sure this buffer is the right size b2ContactResult contactResultCache[MAX_NUM_COLLISIONS]; int32 contactResultCount = 0;   class MyContactListener : public b2ContactListener { public: void Add(const b2ContactPoint* point) { }   void Persist(const b2ContactPoint* point) { }   void Remove(const b2ContactPoint* point) { }   void Result(const b2ContactResult* point) { // TODO we are making a deep copy of every contact point here // check the box2d contact masks to make sure we minimize unwanted contact results contactResultCache[contactResultCount++] = *point; } };   void handleCachedContactResults() { b2ContactResult contactResult; for(int i = 0; i < contactResultCount; i++) { #ifdef BBDEBUG if(contactResultCount >= MAX_NUM_COLLISIONS) { NSLog(@"RAN OUT OF BUFFER"); assert(NO); } #endif contactResult = contactResultCache[i]; SuperBox2DActor* actorOne = (SuperBox2DActor*)contactResult.shape1->GetBody()->GetUserData(); SuperBox2DActor* actorTwo = (SuperBox2DActor*)contactResult.shape2->GetBody()->GetUserData(); if(!actorOne.isDead && !actorTwo.isDead) { [actorOne collisionResultOne:&contactResult withActor:actorTwo]; [actorTwo collisionResultTwo:&contactResult withActor:actorOne]; } }   // clear the collision cache contactResultCount = 0; }   void removeDeadActors() { b2Body* node = bb_world->GetBodyList(); while (node) { b2Body* b = node; node = node->GetNext();   SuperBox2DActor* actor = (SuperBox2DActor*)b->GetUserData(); if (actor.isDead) {   // remove from physics engine bb_world->DestroyBody(b);   // remove from game engine (cocos2d) [[StandardGameController sharedSingleton] removeGameActor:actor]; } } }     @implementation Box2DEngine + (Box2DEngine*)sharedSingleton { static Box2DEngine* sharedSingleton; if (!sharedSingleton) sharedSingleton = [[Box2DEngine alloc] init];   return sharedSingleton; }   - (void)createWorld:(CGSize)size { b2AABB worldAABB; worldAABB.lowerBound.Set(0, 0); worldAABB.upperBound.Set(size.width * BOX2D_SCALE_FACTOR_INVERSE, size.height * BOX2D_SCALE_FACTOR_INVERSE); // TODO this shouldnt be inverse?   b2Vec2 gravity(0.0f, -30.0f); bool doSleep = true;   bb_world = new b2World(worldAABB, gravity, doSleep); bb_world->SetContactListener(new MyContactListener()); }   - (void)deleteWorld { [self unschedule:@selector(step:)]; delete bb_world; bb_world = NULL; }   - (void)runSimulation { [self schedule:@selector(step:)]; }   - (void)step:(ccTime)dt {   // step the world bb_world->Step(dt, velocityIterations, positionIterations); // TODO do i use timestep or dt here?   //BBLog(@"Num of contact results is %d",contactResultCount); // do stuff with collisions handleCachedContactResults();   // remove all actors that are marked as dead removeDeadActors();   // update cocosnode positions for (b2Body* b = bb_world->GetBodyList(); b; b = b->GetNext()) { if (b->GetUserData() != NULL) { SuperBox2DActor *actor = (SuperBox2DActor*)b->GetUserData(); b2Vec2 position = b->GetPosition(); actor.position = b2toCGPoint(position); actor.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle()); //NSLog(@"obj %@ %4.2f %4.2f\n",actor, position.x, position.y); } }   }   @end

Update: This code is obsolete now. You can just do

Label *messageLabel = [Label labelWithString:message dimensions:CGSizeMake(380, 120) alignment:UITextAlignmentCenter fontName:@"your_custom_font" fontSize:26];

by using the new FontManager class. For example, run this once in your app delegate when your program first loads

[[FontManager sharedManager] loadFont:@"your_custom_font"];

It can take a long NSString and create multiple labels without breaking up a word. I’ll eventually use this for my help screen, replacing the current 6 different 480×320 png images that I load for each one  .

The code is simple, but hopefully it might save somebody the time it took me to write it. I had to look up some very basic elements of ObjC here, so if there is a much easier way to do this, please let me know but don’t make too much fun of me.

You can easily switch out the BitmapFontAtlas for just a normal Label and it would work just fine.

(void) setTipString:(NSString*)str {   NSInteger lineChars = 0; BOOL isSpace = NO; NSInteger index = 0; NSInteger numLines = 0;   NSMutableString *line = [NSMutableString stringWithCapacity:LINE_LENGTH];   while (index <= [str length]) { if(index == [str length]) { BitmapFontAtlas *tip = [[BitmapFontAtlas bitmapFontAtlasWithString:[NSString stringWithString:line] fntFile:@"text.fnt" alignment:UITextAlignmentLeft] retain]; [tip setPosition: cpv(30,210 - 20 * numLines)]; [self addChild:tip]; return; }     NSString *tmp = [str substringWithRange:NSMakeRange(index, 1)]; [line appendString:tmp];   if([tmp isEqual:@" "]) isSpace = YES; else isSpace = NO;   if(lineChars >= LINE_LENGTH && isSpace) { BitmapFontAtlas *tip = [[BitmapFontAtlas bitmapFontAtlasWithString:[NSString stringWithString:line] fntFile:@"text.fnt" alignment:UITextAlignmentLeft] retain]; [tip setPosition: cpv(30,210 - 20 * numLines)]; [self addChild:tip]; lineChars = -1; [line setString:@""]; numLines++; } lineChars++; index++; } }

Posted by 오늘마감

댓글을 달아 주세요

아이폰어플개발정보2010. 6. 22. 09:47
UItableView customizing with Addressbook (네번째 스터디)
안녕하세요.. 금일은 전 시간에 진행했던 테이블뷰에 대해서 쪼금 더 심도 있게 진행을 하겠습니다.
제목을 봅시다... 네 테이블뷰의 커스텀마이징 입니다...

@ 학습목표
- UITableViewCell 을 이용하여 테이블뷰 꾸미기
- ABAddressbook 프레임 워크 이용하기

개요를 말씀드리자면 IB를 이용한 커스텀셀을 생성하는 방법과 코딩으로 하는 방법 2가지가 있습니다 우선 모두다 해보겠습니다.
추가적인 보너스로 테이블의 내용을 iPhone 내부의 주소록을 데이터를 이용하여 만들어 보겠습니다..
이름하여 인맥북!!!! ㅋㅋ 귀찮으시더라도 시뮬레이터의 주소록에 이미지를 추가해 놓습니다. 그래야 이미지가 나와요..

먼저 뷰콘트롤러 기반의 포르젝트를 생성합니다.. 저는 ownLinks 라고 명명.. 하겠습니다. 
IB를 로드 해서 UITableView 를 추가합니다. 그리고 UITableView를 선택해서 connection을 설정합니다. delegate, dataSouce는 File's Owns와 연결을 합시다.. 그리고 세이브 해주시고 소스 코드로 돌아갑니다.



먼저 IB를 사용 하지 않고 Cell 을 디자인 해보겠습니다.
addressbook을 사용하기 위해서는 AddressBook/AddressBookUi 라는 2가지 프레임워크를 이용합니다. 
먼저 AddressBook 프레임 워크 입니다.. 네 이건 주소록 데이터를 읽어오고 편집 추가 저장 등을 할 수 있는 메서드들을 제공합니다.
두번째 프레임 워크인 AddressBookUI 는 말그대로 UI와 데이터를 연결하는 Delegate 메서드를 정의 합니다(사용은 아직 안해봐서 정확한 표현인지는 모르겠습니다만...)

저는 주소록의 데이터를 제가 만든 커스텀마이징된 테이블뷰에 넣기 위해서  AddressBook 프레임 워크만을 사용하였습니다.

프레임워크 파일을 프로젝트에 추가 합니다.

                                       

먼저 viewController.h 파일에 사용할 프레임 워크를 인포트 하고 프로토콜들을 추가 합니다.

#import <UIKit/UIKit.h>
#import <AddressBook/AddressBook.h> // 프레임워크 추가
//UITableViewCell 하위 뷰의 구분자 선
#define kNameValueTag 1
#define kNumberValueTag 2
#define kImageTag 3

@interface ownLinksViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, > {
}
@end

다음는 바디 코드 입니다. 나머지 부분은 생략을 하고 제일 중요한 프로토콜 구현 부부입니다.

#pragma mark -
#pragma mark Table View Data Source Methods

-(NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
{
        // 테이블 수는 연락처에 입력된 연락처 수
ABAddressBookRef addressBook = ABAddressBookCreate();
NSInteger size = (NSInteger)ABAddressBookGetPersonCount(addressBook);
CFRelease(addressBook);
return size;
}

//tag값에 선언된 상수를 입력하여 해당 서버 뷰들을 구분한다.

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//cell 구분자 언언
static NSString *CellTableIdentifier = @"CellTableIdentifier ";
//cell 존재 검사
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellTableIdentifier];
if (cell == nil) {
              //cell 선언
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault  reuseIdentifier:CellTableIdentifier] autorelease];
        
               //cell에 들어갈 이미지 설정 
     CGRect imageViewRect = CGRectMake(5, 5, 30, 30);
UIImageView *personView = [[UIImageView alloc] initWithFrame:imageViewRect];
personView.tag = kImageTag;
[cell.contentView addSubview:personView];
[personView release];
        CGRect nameLabelRect = CGRectMake(35, 5, 65, 15);
        UILabel *nameLabel = [[UILabel alloc] initWithFrame:nameLabelRect];
        nameLabel.textAlignment = UITextAlignmentRight;
        nameLabel.text = @"Name:";
        nameLabel.font = [UIFont boldSystemFontOfSize:12];
        [cell.contentView addSubview: nameLabel];
        [nameLabel release];
        
        CGRect numberLabelRect = CGRectMake(35,25, 65, 15);
        UILabel *numberLabel = [[UILabel alloc] initWithFrame:numberLabelRect];
        numberLabel.textAlignment = UITextAlignmentRight;
  numberLabel.text = @"Number:";
        numberLabel.font = [UIFont boldSystemFontOfSize:12];
        [cell.contentView addSubview: numberLabel];
        [numberLabel release];
        
        CGRect nameValueRect = CGRectMake(110, 5, 200, 15);
        UILabel *nameValue = [[UILabel alloc] initWithFrame:nameValueRect];
        nameValue.tag = kNameValueTag;
        [cell.contentView addSubview:nameValue];
        [nameValue release];
        
        CGRect numberValueRect = CGRectMake(110, 25, 200, 15);
        UILabel *numberValue = [[UILabel alloc] initWithFrame:numberValueRect];
        numberValue.tag = kNumberValueTag;
        [cell.contentView addSubview:numberValue];
        [numberValue release];
        
}
//선택된 인덱스
 NSUInteger row = [indexPath row];  

//ABAdrressBookCreate()를 이용하여 현재 주소록 객체를 생성
ABAddressBookRef addressBook = ABAddressBookCreate();
//저장된 개인목록을 복사(Group 데이터는 ABAddressBookCopyArrayOfAllGroups를 이용
//개인 목록과 그룹 목록으로 구분되어 저장되어 있
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
//선택된 row 의 개인 정보 가져옴 
ABRecordRef ref = CFArrayGetValueAtIndex(allPeople, row);

//태그를 이용하여 라벨을 찾는다.
  UILabel *name = (UILabel *)[cell.contentView viewWithTag:kNameValueTag];
//개인정보 중 firstname 만 복사함 kABPersonFirstNameProperty 같은 각각의 인자가 정의 되어 있다.
name.text = (NSString *)ABRecordCopyValue(ref, kABPersonFirstNameProperty);

//전화번호부를 복사 여러개의 전호 번호가 존재하기 때문에 해당 데이터는 멀티 값을 가지는 배열로 저장되어 있다.
ABMutableMultiValueRef multi =  ABRecordCopyValue(ref, kABPersonPhoneProperty);
NSArray* phoneNumbers = (NSArray*)ABMultiValueCopyArrayOfAllValues(multi);
//전화 번호가 없는 경우 nil 값을 가진다.
if (phoneNumbers != nil) {
UILabel *number = (UILabel *)[cell.contentView viewWithTag:kNumberValueTag];
                //전화 번호는 배열로 저장되어 있기 때문에 원하는 정보가 위치한 index를 인자로 넘겨준다.
number.text = [phoneNumbers objectAtIndex:0];
}
//이미지를 가지는 검사 
if (ABPersonHasImageData(ref)) {
    // 이미지를 복사 하여 이미지 뷰에 입력
     // CFDataRef 데이터 형식으로 리턴된다. 형변환을 하여사
UIImage *personImage = [[UIImage alloc] initWithData:(NSData*)ABPersonCopyImageData(ref)];
UIImageView *imageView = (UIImageView *)[cell.contentView viewWithTag:kImageTag];
imageView.image = personImage;
[personImage release];
}
//프레임워크를 이용하여 생성된 객체(포인터아님)자원은 CFRelease를 이용하여 해제한다. 
CFRelease(multi);
CFRelease(ref);
//문제 발생
//ABAddressBookCreate, ABAddressBookCopyArrayOfAllPeople 를 이용하여 생성된 객체
//둘다 해제하게되면 메모리 크래쉬가 일어 난다. 둘중에 하나만 해제를 하여 사용
//원인을 추축하면 생성되는 시 같은 데이터를 참조하는게 아닐까 하는 추축이다... 구글링을 좀더 해서 원인을 
//파악해 야될것 같네요.
CFRelease(addressBook);
//주석처리..
// CFRelease(allPeople);

return cell;
}

이것을 실행하면 아래와 같이 나옵니다..




IB를 이용하는 방법은 이어 작성 하겠습니다.





 



출처 : http://blog.naver.com/PostView.nhn?blogId=coderider&logNo=50088797458
Posted by 오늘마감

댓글을 달아 주세요

아이폰어플개발정보2010. 6. 21. 23:56
[번역] Getting started with Data Management

번역을 링크로 올리지 말라는 카페 운영진에게 이멜을 받았습니다.
그래서, 이번 번역을 여기에 원본을 그대로 올리구요.
다음 번역부터는 제 블로그에만 올리겠습니다.
번역 문서는 계속 업뎃될 예정이구요. 필요하신 분들은 제 블로그로 와주세요.

역자주원문에서계속사용되고있는 라는단어는현재여기에서는가리키고있지만애플이이러한기술문서를특정하드웨어로국한시키지않으려는같아서역시도앞으로있을지모르는애플의행보를위해서원문그대로의뜻인 장치번역을했어요참고

데이터관리를시작하기

개요

모든 iPhone 어플리케이은데이터를가상적으로관리할필요가있습니다데이터관리는문자열대용량텍스트이진데이터날짜컬렉션속성리스트그리고데이터를포함하는프로그램에서사용가능한다양한데이터형의생성과처리를위해지원합니다어플레이케이션은로컬디비파일폴더그리고번들에데이터를저장하고가져오기위해데이터관리인터페이스를이용합니다이들은또한이벤트와알림같은다른형태의메시지를적절하게받고응답하기위해데이터관리인터페이스를이용합니다

데이터관리인터페이스들은몇몇의다른프레임웍에존재하고있습니다기본적인프레임웍들은다음과같습니다이것은기반의프레임웍이며위에서그래픽이벤트중심의어플리케이션을구현하기위한핵심환경을제공합니다사용자인터페이스데이터를관리하기위해 UIResponder, UIApplication, UIEvent 같은클래스를포함하고있습니다이것은기반의프레임웍이며어플리케이션의어떠한형태에서도사용될있는클래스들의기본계층들을정의하고있습니다클래스는수치형문자열컬렉션과같은기본자료형을위해서오브젝트포장또는이와동일한것들을제공합니다또한포트쓰레드그리고파일시스템과같은기본적인시스템개체와서비스로의접근을위한유틸리티클래스를제공합니다이것은객체도식관리와영속성을위해일반화된프레임웍입니다이것은취소재실행변경의전달과같은기능객체들사이의관계일치성을관리하는것과외부의데이터저장소객체를저장하는것들을포함하여위한지원을포함하고있습니다개념적으로프레임에서상속된프로그래밍인터페이스의집합입니다하지만이것은언어를이용하여구현되어있습니다데이터객체들문자열컬렉션시간날짜포트어플리케이션실행루프상호의사소통그리고선택대한추상형을정의합니다역자주문단에서선택으로번역했지만이러한데이터객체에대한의미는경험하고나야좀더의미에가깝게번역할있을같네요그리고역시현재로서는추상형외에는다르게다가오는의미가없네요기본

여러분이코드를작성하기이전에어플리케이션을설계하는방법에대해배우기위해서는iPhone Application Programming Guide안의The Core Application읽어야합니다프로그래밍인터페이스와이것을사용하는방법에대해배우기위해서는동영상자료인iPhone Application Development - Getting Started] 시청해주기바랍니다또한화학적인요소데이터를저장하고다른많은비주얼모드로데이터를표현하기위해속성리스트를사용하는어플리케이션TheElements] 샘플코드프로젝트를읽어주기바랍니다다음단계들여러분의소프트웨어에서데이터관리를지원하기위해여러분은여러분만의요구와경험을위해어느프레임웍을사용할것인지를결정해야합니다만일여러분의소프트웨어가사용자인터페이스를갖고있다면여러분은아마도멀티터치이벤트를처리해야것입니다여러분은어플리케이션수준에서사용자에게선택을제공하기원할것입니다여러분은또한장치의방향성가속도계의또는장치의위치위치값알기를원할것입니다 

어느프레임웍을사용할지를결정하기

몇몇의다른프레임웍은개발자들의어플리케이션에서그들이데이터를관리할있도록돕기위해서인터페이스들을지원합니다이것을시작하기위해서만일여러분이처음접한다면Foundation Framework Reference시작하면서프레임웍안의클래스들에대해서배우시기바랍니다프레임웍은배열딕셔너리문자열날짜그리고시간들과같은데이터와동작하기위한클래스들을포함하고있습니다이것은또한파일시스템과동작하기위한클래스들도포함하고있습니다만일여러분이코코아개발자이라면UIKit Framework Reference] 시작하면서프레임웍안의클래스들에대해서배우시기바랍니다프레임웍은가속장치화면이벤트응답기그리고터치와같은데이터와동작하기위한클래스들을포함하고있습니다만일여러분이이미개발에경험이있다면일반적인객체도식관리를위해사용하는방법에대해배우기위해서Getting Started with Core Data에서관련된경로를따라가기바랍니다만일여러분이기본적인데이터관리를위해인터페이스를살펴보고싶다면Core Foundation Framework Reference시작하십시오프레임웍은배열딕셔너리문자열번들그리고파일식별자같은데이터와동작하기위한추상형들을포함하고있습니다장치의현재위도와경도를결정하는방법에대해배우기위해Core Location Framework Reference으로시작하기바랍니다만일여러분이장치안에연락처에접근해야한다면Address Book Framework Reference으로시작하기바랍니다프레임웍을이용하여여러분은연락처디비안의사람과그룹들에여러분이원하는속성을추가하거나기존정보를가져올있습니다멀티터치이벤트를처리하기

에서터치는화면위에손가락의접촉또는움직이라는것을말합니다그리고이것은독특한멀티터치연속의부분입니다만일여러분의프로그램이사용자인터페이스를갖고있다면이것은아마도멀티터치이벤트를처리해야것입니다이것을시작하기위해서에서의이벤트에대해서는iPhone Application Programming Guide안의Event Handling읽어주기바랍니다그리고이러한이벤트들은멀티터치이벤트인터페이스모델을바탕으로하고있습니다TheElements] 샘플프로젝트를참고하십시오이것은멀티터치의확대축소그리고스크롤을처리하는것을보여주고있습니다어플리케이션수준에서의선택제공하기

선택이란어플리케이션의동작또는겉모습을설정하기위해사용되는세팅들입니다장치의사용자들은어플리케이션에게자신들이설정한환경을항상같은방식으로표현해주기를기대합니다이것을시작하기위해서시스템이제공하는어플리케이션을이용하여어플리케이션수준에서의선택을제공하는방법을배우기위해iPhone Application Programming Guide] 안의Application Preferences읽기바랍니다Metronome이라는샘플코드프로젝트를참고하십시오이것은진동자의박자를세는방법의간단한예를보여주고있습니다프로젝트는또한어플리케이션에제공된선택을저장하는방법에대한예도보여주고있습니다만일여러분이어플리케이션에의한제공되는것보다많은융통성을필요로한다면여러분은프레임웍안의클래스를사용하여여러분의어플리케이션에서선택을관리할있습니다자세한정보는User Defaults Programming Topics for Cocoa읽기바랍니다가속도계의이벤트에접근하기

가속도계는주어진선형경로를따라가는속도로변화를측정합니다장치는개의가속도계를갖고있습니다하나는장치의기본좌표의각각을기준으로하는것입니다만일여러분이가속도계의데이터를받는것에관심이있고여러분의어플리케이션에서값을받는것에관심이있다면여러분은 UIKit 프레임웍안의클래스를사용하여작업을있습니다이것을시작하기위해서가속도계의이벤트를설정하고받는방법을배우기위해서는iPhone Application Programming Guide] 안의“Accessing Accelerometer Events”읽어야합니다BubbleLevel] 샘플코드프로젝트를참고하십시오이것은시각적인버블수치역자주어떤벡터값을얘기하는같은데요버블레벨이몬지모르겠어서그냥 버블수치번역해요경사계값을생성시키기위해가속도계의값을사용하고있습니다이것은장치의현재방위값을확인하는방법도보여주고있습니다장치의위치값을얻어오기

장치는장치의현재위치이용가능한신호정보를갖고서위치고정을삼각법으로측정하여현재위치를결정할있는하드웨어를포함하고있습니다여러분은고도와고도의수직정확성장치의지리적좌표값을얻기위해프레임웍안의클래스를사용할있습니다이것을시작하기위해서Core Location Framework Reference읽기바랍니다여러분은위치관련의이벤트들의전송을설정하고계획또는예약시키기위해서프레임웍안의클래스들과프로토콜들을사용합니다위치값을업데이트시키고처리하는방법을배우기위해서는iPhone Application Programming Guide] 안의“Getting the User'™s Current Location”읽기바랍니다연락처정보에접근하기

역자주연락처로직접번역하기보다는아이폰의처럼하나의빌트인어플리케이션으로이해해야맞을같네요연락처와다른개인정보를위해한곳으로집중화된디비를말합니다연락처정보는이메일과채팅프로그램과같은소프트웨어에게는중요한것입니다시작하기위해서여러분의어플리케이션에서연락처디비를접근하는방법을배우기위해위한읽기바랍니다여러분은사용자의연락처데이터에접근할있을뿐만아니라데이터에여러분의속성과행동을구현할수도있습니다역자주개발자가연락처정보를마음대로가공할있다는의미를복잡하게설명하네요

Posted by 오늘마감

댓글을 달아 주세요

아이폰어플개발정보2010. 6. 21. 23:55
[번역] Getting started with iPhone

iPhone OS 를 시작하기

iPhone OS iPhone iPod 터치 장치들을 위한 어플리케이션을 만들기 위해서 여러분이 사용하는 운영 시스템과 기술을 포괄적으로 의미합니다. iPhone OS 안의 기술은 터치 이벤트에 응답하고 고품질의 그래픽을 출력하는 향상된 어플리케이션을 만들기 위해 여러분에게 필요한 모든 것을 제공합니다. 이러한 기본적인 어플리케이션 환경에 더불어, iPhone OS 는 여러분에게 멀티-터치 이벤트로의 접근, 하드웨어 가속도계로의 접근, 향상되고 진보된 어플리케이션을 쉽게 만들게 하는 장치에서 제공하는 기능의 접근을 제공합니다.

iPhone SDK iPhone OS, Xcode 툴들, 그리고 문서와 샘플 코드, 여러분이 어플리케이션을 개발할 때 필요로 하는 리소스를 갖고 있습니다. iPhone SDK Xcode 툴들은 Mac OS X v10.5 혹은 그 이상 버전이 실행되고 있는 인텔 기반의 맥킨토시에서 사용될 수 있습니다. Xcode 는 여러분의 어플리케이션 코드를 생성하고, 컴파일하고, 실행하고, 디버깅하는데 필요한 개발 환경을 제공합니다. Xcode 는 완벽히 iPhone OS 에 통합되어 있기 때문에, 이것을 갖고 iPhone 어플리케이션을 개발하는 것은 어렵지 않습니다.

iPhone SDK 를 얻는 방법은 아래의 링크를 찾아가세요. http://developer.apple.com/iphone/[] [iPhone OS Overview] [] [Tools for iPhone OS Development] [] [Learning Objective-C: A Primer] Creating an iPhone Application] MoveMe]

[] iPhone Development Guide [] iPhone Application Programming Guide iPhone [] Your First iPhone Application [] iPhone Human Interface Guidelines [] Cocoa Fundamentals Guide [] The Objective-C Programming Language iPhone OS Technology Overview §Getting Started with Audio & Video

§Getting Started with Data Management

§Getting Started with Graphics and Animation

§Getting Started with Networking & Internet

§Getting Started with Performance

§Getting Started with Security

§Getting Started With User Experience

Posted by 오늘마감

댓글을 달아 주세요

아이폰어플개발정보2010. 6. 21. 23:55
[번역] Getting started with Audio and Video

원본 링크: http://developer.apple.com/iphone/library/referencelibrary/GettingStarted/GS_AudioVideo_iPhone/index.html

역자주: 오디오와 비디오의 play 를 구분하기 위해 오디오는 연주(play), 비디오는 재생(play) 이라고 번역을 했어요. 참고^^; 그리고 이 번역부터는 원본 문단에 있는 링크를 복사해 오지 않으려고 합니다. 링크 가져오는게 무척 번거럽네요. 지송^^;

오디오와 비디오로 시작하기

개요
iPhone OS 의 멀티미디어 기술은 여러분이 iPhone OS 장치의 사용하기 편리한 오디오와 비디오 기능을 이용할 수 있게 합니다. 여러분
의 어플리케이션에서 오디오를 생성, 녹음, 믹스, 편집, 연주하는 것이 필요하다면 Core Audio 를 사용하시기 바랍니다. 오픈소스로 제공되는 OpenAL 인터페이스는 고성능의 위치 지정이 가능한 연주를 지원하며, 게임에 가장 이상적입니다. Media Player 프레임웍은 비디오 파일의 꽉찬 화면의 재생을 지원하며, 사용자의 iPod 라이브러리 안의 오디오들의 재생도 제공합니다. iPhone OS 3.0 에서 부터 여러분은 여러분의 어플리케이션에 비디오 녹화 기능 또한 추가할 수 있습니다.

기본

여러분이 오디오 관련 코드를 작성하기 전에...

[] [Core Audio Overview] 안의 [What Is Core Audio] 을 읽어야 합니다. 이것으로 여러분은 iPhone OS 에서 오디오 서비스로의 기본적인 인터페이스에 친숙해져 합니다.

[] 또한 iPhone OS 위에서의 오디오 관련 개발을 배우기 위해서 [iPhone Application Programming Guide] 안의 [Using Sound in iPhone OS] 를 읽어야 합니다.

[] 이것의 구조, 프로그래밍 규약, Core Audio 의 사용을 배우기 위해서 [Core Audio Overview] 안의 [Core Audio Essentials] 역시 읽어주기 바랍니다.

[] 사운드를 연주하는 방법을 보여주는 [avTouch] 샘플과 기본적인 녹음과 연주를 보여주는 [SpeakHere] 샘플, 그리고 진동을 발생시키고(역자주: 모바일의 진동음을 이야기하는 것 같네요) 경고음을 연주하고 사용자를 위한 음향 효과를 만드는 방법을 보여주는 [SysSound] 샘플을 참고해야 합니다.

비디오 관련 코드를 작성하기 전에...

[] iPhone OS 위에서의 비디오 녹화와 재생의 기본적인 내용을 위해서는 [iPhone Application Programming Guide] 안의 [Using Video in iPhone OS] 를 읽어주기 바랍니다.

다음 과정들

여러분이 작성하려는 어플리케이션의 요구 사항을 바탕으로 오디와 비디오 관련의 다양한 API 를 선택할 것입니다. 모든 iPhone 개발자들은 오디오 세션에 대해서 배울 필요가 있습니다.

오디오 세션을 사용하기

iPhone OS 내의 Audio Session Service 를 이용하여 여러분은 걸려오는 전화와 같은 인터럽트에 대한 어플리케이션의 대응 처리를 관리할 수 있으며, 사용자들이 헤드셋을 모바일에서 뽑았을 때 처럼의 오디오 흐름 변화를 관리할 수 있습니다. 이러한 기술을 이용하여 또한 여러분은 오디오의 상태를 지정할 수 있습니다. 가령 사용자가 [링/무음] 상태에서 [무음] 상태로 변경을 할 때 여러분의 오디오를 정지시킬 것인지 아니면 계속 지속시킬 것인지 설정할 수 있습니다.

오디오를 사용하는 모든 iPhone 어플리케이션은 반드시 Audio Session Services 를 사용해야만 합니다. 더 많은 정보를 위해서는, [Audio Session Programming Guide] 를 읽어 주시기 바랍니다. 녹음과 재생이 필요한 어플리케이션에서 이러한 기술을 사용하는 방법의 예는 [SpeakHere] 샘플을 참고하시기 바랍니다.

오디오를 연주하기
여러분의 필요에 따라서, 여러분은 AVAudioPlayer 클래스, Audio Queue Services, OpenAL, I/O 오디오 unit 또는 System Sound Services 를 이용하여 iPhone OS 에서 오디오를 연주할 수 있습니다. 또한 여러분은 iPod Library Access API 들을 이용하여 사용자의 iPod 라이브러리에 있는 오디오들을 연주할 수 있습니다.

[] 임의 구간의 사운드를 연주하거나, 동시에 여러 사운드를 연주하거나, 레벨 제어를 하면서 사운드를 연주하기 위해서는, AVAudioPlayer 클래스를 이용합니다. 이러한 기술은 MP3, AAC, ALAC(애플의 무손실 포맷), IMA4, 선형 PCM 포맷은 물론이고 iPhone OS 에서 제공되는 어떠한 종류의 오디오 포맷을 연주할 수 있습니다. 이러한 기술을 위해서 [iPhone Application Programming Guider] 와 [AVAudioPlayer Class Reference] 를 참고하십시오. 또한 [avTouch] 샘플도 참고하십시오.

[] 정밀한 제어를 하면서 사운드를 연주하기 위해서 (가령 동기화를 위해서), 또는 인터넷 스트리밍을 캡처한 오디오를 연주하기 위해서는, [Audio Queue Services] 를 사용합니다. 더 자세한 내용은 [Audio Queue Services Programming Guide] 를 참고하십시오. 샘플 코드는 [SpeakHere] 를 보십시오.

[] 위치를 지정하여 오디오를 연주하기 위해서(특히 여러분의 어플리케이션이 게임이라면), OpenAL 를 사용하십시오. 이것은 http://openal.org 에서 소개되어 있습니다. 이 기술을 사용한 것에 대한 중요한 정보를 위해서 OpenAL FAQ 를 참고하십시오. 샘플 코드는 [oalTouch] 를 보십시오.

[] 가장 저수준의 I/O 접근을 하면서 사운드를 연주하기 위해서, 또는 동일한 시간에 오디오의 입력과 출력을 제공하기 위해서는, I/O 오디오 유닛을 사용합니다. 음성 채팅 어플리케이션을 위해서는 Voice Processing I/O 오디오 유닛을 사용합니다. 자세한 내용은 [System Audio Unit Access Guide] 와 [aurioTouch] 샘플을 참고하십시오.

[] 경고음을 연주하거나, 사용자 인터페이스를 위한 사운드 효과를 연주하거나, 진동음을 발생시키기 위해서는 System Audio Services 를 사용합니다. 이 기술은 .caf, .wav, .aif 포맷의 30초 또는 그 이하 길이를 갖는 사운드를 연주할 수 있습니다. 자세한 내용은 [iPhone Application

Programming Guider] 에서 [Using Sound in iPhone OS] 를 참고하십시오.

[] 사용자의 iPod 라이브러리에 있는 오디오를 연주하기 위해서는 Media Player 프레임웍에 있는 iPod Library Access API 들을 사용하십시오.  자세한 내용은 [iPod Library Access Programming Guider] 를 참고하십시오. 또한 샘플은 [AddMusic] 을 보십시오.

스트리밍되는 오디오를 사용하기

여러분은 스트리밍되는 오디오를 캡처하거나 연주할 수 있습니다.

[] 네트웍 연결로 부터 스트리밍되는 오디오를 분석하기 위해서는, [Audio File Stream Services Reference] 에서 설명된 [Audio File Stream Services] 를 사용합니다.

[] 캡처된 스트리밍 오디오를 연주하기 위해서는, [Audio Queue Services Programming Guide] 와 [Audio Queue Services Reference] 를 보십시오.

[] 여러분은 MPMoviePlayerController 클래스를 사용하여 AAC-LC 포맷으로 된 인터넷 오디오 파일 또한 연주할 수 있습니다. 이것에 대한 예는 [MoviePlayer] 샘플을 참고하시기 바랍니다.

오디오를 녹음하기

iPhone 에서 사운드를 녹음하기 위해서는, [AVAudioRecorder Class Reference] 에서 설명된 것처럼 [AVAudioRecorder] 를 사용하십시오.

여러분은 또한 [Audio Queue Services Programming Guide] 와 [Audio Queue Services Reference] 에서 설명된 [Audio Queue Services] 를 사용하여 사운드를 녹음할 수도 있습니다. iPhone OS 에서 지원되는 모든 종류의 오디오를 녹음하는 방법은 [SpeakHere] 샘플에서 볼 수 있습니다.


 

비디오를 재생하기
MPMoviePlayerController 클래스는 H.264 (baseline profile level 3.0) 포맷으로 또는 MPEG-4 part 2 (simple profile) 의 비디오 포맷으로 비디오 재생을 지원합니다. 비디오 재생은 꽉찬 화면을 지원하며 주로 애니매이션 재생이 필요한 게임 개발자를 위해 특화되어 있습니다.

여러분은 또한 [MoviePlayer] 샘플에서 보여지는 것처럼 인터넷으로 부터 스트리밍되는 비디오를 재생하기 위해서 MPMoviePlayerController 클래스를 사용할 수 있습니다. 여러분의 어플리케이션에 비디오 재생 기능을 추가하는 것에 대한 자세한 내용은 [iPhone Application Programming Guide] 안에 [Playing Video Files] 를 읽기 바랍니다.

비디오를 녹화하기
iPhone OS 3.0 에서 부터, 여러분은 지원되는 장치 바탕으로 오디오를 포함하고 있는 비디오를 녹화할 수 있습니다. 단지 정지 이미지를 캡처하는 것에 대해서는 UIImagePickerController 클래스를 사용합니다. 자세한 내용은 [iPhone Application Programming Guide] 안에 [Recording Video] 를 참고하시고,  [UIImagePickerController Class Reference] 도 참고하기 바랍니다.

추가 리소스들

iPhone Dev Center 는 여러분의 어플리케이션에 멀티미디어 기능 추가를 위해서 기본적인 지침, 참고 문서와 기술 조언, 샘플 코드를 제공합니다.

Core Audio 메일링 리스트 (coreaudio-api@lists.apple.com) 는 같은 관심사를 갖고 있는 개발자들과 Core Audio 와 OpenAL 관련 문제를 토론할 수 있는 매우 훌륭한 수단입니다.

iPhone 개발자 포럼에서 여러분은 질문을 하거나 어떠한 주제 또한 모든 iPhone 개발 주제에 대한 답변을 볼 수 있습니다.


 



출처 : http://blog.naver.com/PostView.nhn?blogId=dontbeshy&logNo=90082203564
Posted by 오늘마감

댓글을 달아 주세요

아이폰어플개발정보2010. 6. 21. 23:55
[번역] Getting started with Networking and Internet.

원본 링크: http://developer.apple.com/iphone/library/referencelibrary/GettingStarted/GS_Networking_iPhone/index.html

네트웍과 인터넷으로 시작하기

개요

iPhone 의 O/S 는 몇가지의 프레임웍과 라이브러리를 갖고 있으며, 이것은 네트웍과 인터넷을 기반으로 하는 여러분들의 어플리케이션에서 사용하도록 제공하는 것입니다. 따라서 여러분들은 Foundation 과 Core Foundation 또한 CFNetwork 과 BSD 소켓들을 이용하여 일반적인 네트웍 프로토콜과 서비스에 접근할 수 있습니다.

[] Foundation 은 Objective-C 기반의 프레임웍이며, CFNetwork 의 API 사용을 위한 객체 지향형의 추상화(abstraction)를 제공합니다.

[] Core Foundation 은 C 기반의 프레임웍이며, URL 자원을 생성, 접근, 갱신 또는 삭제하기 위한 편리하고(다른 것들에 비해서) 시스템에 독립적인 방법을 제공합니다.

[] CFNetwork 은 C 기반의 프레임웍이며, 여러분들의 어플리케이션의 다양한 네트웍 처리를 위해서 제공된 것입니다. 가령, 실행 루프를 갖는 소켓들의 통합과 HTTP 와 FTP 서버들과의 의사 소통이 예가 될 수 있습니다.

[] CFNetServices 는 C 기반의 API 이며, 이것으로 여러분은 Bonjour 네트웍 서비스를 찾거나 등록할 수 있습니다; 가령 프린터나 파일 서버 등을 말합니다.

[] BSD 네트웍 API (libSystem 의 일부인) 들은 저수준의 소켓 함수들이며, 만일 여러분들이 이미 다른 플랫폼을 경험해 본 적이 있다며, 이것은 여러분에게 어렵지 않을 것입니다.

여러분이 이러한 인터페이스를 사용할 때, 여러분은 Wi-Fi 또는 모바일 기반의 신호를 선택할지 고민할 필요가 없습니다.

이 인터페이스들은 자동적으로 기본적인 하드웨어 장치에 접근하며, 최적의 신호를 선택하고, 필요에 따라 신호들 사이에서 끊김없이 부드럽게 왔다갔다 할 수 있습니다.

기본

여러분이 코드를 작성하기 이전에 아래 사항을..

[] iPhone OS 환경 위에서의 네트웍 어플리케이션을 개발할 때,
고려해야 할 문제들에 언급하고 있는 [Document Transfer Strategies]
를 읽으시기 바랍니다.

[] 여러분의 네트웍 관련 코드를 작성하기 위해 여러분이 선호하는 언어를 선택합니다. iPhone OS 는 C 와 Objective-C 로 작성된 네트웍 코드를 지원합니다. 여러분의 선택은 여러분이 가장 편안하게 느끼는 언어에 따라 결정하는 것과 다른 플랫폼으로 부터 기존 네트웍 코드를 가져올 것이냐에 따라 결정됩니다.

[] 여러분이 소켓을 통해 직접 작업할 것인지, 추상 계층을 사용할 것인지 결정합니다.

[] iPhone OS 는 소켓을 통해 직접 작업하는 것을 불필요하게 만드는 것으로 대부분의 소켓 상호 작용 기능을 위해서 편리한 추상 계층을 제공합니다.

[] 기존 네트웍 서비스를 찾기 위해서 Bonjour 를 사용할 것인지 새로운 것들을 등록할 것인지를 결정합니다.

여러분이 위의 과정을 거친 다음에는, 여러분은 어떤 네트웍 API (기존 또는 여러분이 원하는 것들 중에서) 을 선택할 것인지 알 수 있게 됩니다.

다음 과정들
만일 여러분이 네트웍 위에서 작동하는 어플리케이션을 개발한다면, 여러분은 네트웍 프로토콜과 서비스를 이용하기 위해서 iPhone OS 가 제공하는 API 들에 익숙해지기를 원할 것입니다. 만일 여러분이 웹서버와 연동되는 어플리케이션을 개발한다면, 예를들어, 여러분은 Core Foundation 또는 Foundation 에 포함된 애플의 HTTP 기반의 API 를 선택할 것입니다. 만일 소켓을 직접 사용하는 어플리케이션을 개발한다면, 여러분은 다양한 소켓 API 를 이해해야만 합니다. 이러한 과정이 서로 분리된 것처럼 보임에도 불구하고, 이러한 것들은 필수적으로 상호 독립적이지는 않습니다.(역주: 서로가 상당히 연관이 있을 수 밖에 없다는 얘기인것 같네요.)

URL 을 이용하여 리소스를 다운로드하기
Cor Foundation URL 접근 유틸리티, 즉 CFURL 과 NSURL API 는 가장 기본적으로 제공되며, 이들은 웹서버 또는 FTP 서버로 부터 개개의 파일들 또는 다른 리소스들의 다운로드를 위해 쉬운 방법을 제공하고 있습니다.

[] C 기반의 CFURL 은 Core Foundation 프레임웍 중의 일부입니다. 여러분은 [CFURL Reference] 에서 자세한 내용을 배울 수 있습니다.
[] Objective-C 기반의 NSURL 은 Foundation 프레임웍 중이 일부입니다. 여러분은 [NSURL Class Objective-C Reference] 에서 자세한 내용을 배울 수 있습니다.

HTTP 와 FTP Stream 을 이용한 웹과 파일 서버와 연동하기
만일 여러분의 어플리케이션이 CFURL 또는 NSURL 에 의해 제공되는 기능을 통해 웹서버 또는 FTP 서버와 연동하는 것이 필요하다면, 여러분은 CFHTTPStream 과 CFFTPStream API 들을 사용해야 할 것입니다. 이들은 HTTP 의 GET, POST 요청, HTTP 의 쿠키와 요청 헤더 관리, FTP 의 디렉토리 조회, FTP 의 파일 업로딩과 같이 복잡한 HTTP 와 FTP 의 요청에 대한 지원을 제공합니다.

일반적으로 이러한 API 를 배우기 위해서는, [CFNetwork Programming Guide] 를 참고해야 합니다. 자세한 API 관련 문서는 [CFHTTPStream Reference] and [CFFTPStream Reference] 를 참고하시기 바랍니다.

소켓을 이용하여 통신하기

만일 여러분이 소켓을 사용한다면, iPhone OS 에서 제공하는 실행-루프 소켓의 통합 API 를 사용할 수 있으며 또한 이러한 API 에 있는 BSD 소켓으로의 직접 접근을 사용할 수 있습니다.

[] 만일 여러분이 맥 OS X 기반의 네트웍 어플리케이션을 계획하고 또한 iPhone OS 기반의 네트웍 어플리케이션을 만들고 싶다면, 여러분은 동일한 네트웍 API 들을 이용할 수 있습니다.

만일 소켓 수준의 CFNetwork API 로 작업하기로 결정한다면, 여러분은 [CFNetwork Programming Guide] 와 [CFNetwork Framework Reference] 을 반드시 참고해야 합니다.

[] iPhone OS 에서 BSD (POSIX) 네트웍 API 제공됨에도 불구하고, 여러분은 이들을 사용하지 말아야한다. 만일 소켓으로 직접 통신한다면, 즉 On-demand 방식의 VPN 과 같은 iPhone OS 의 특정 네트웍 기능, 이러한 직접 통신을 사용하지 않기를 바랍니다. 대신 [CFStream Socket Additions] 에서 제공되는 API 를 사용해야 합니다.

BSD (POSIX) 네트웍에 대해 알기 위해서는,  예제 코드와 일반적인 정보를 위해서 [UNIX Socket FAQ] 웹사이트를 참고해야 합니다. API 에 대한 자세한 내용은 [iPhone OS 의 메뉴얼 페이지]에서 소켓(2) 를 읽어주기 바랍니다.

네트웍 서비스를 등록하기와 찾기

여러분은 Bonjour 를 사용하여 네트웍 서비스를 찾거나 네트웍 서비스를 등록할 수 있습니다.
이것을 하기 위해서는, C 기반의 CFNetServices 또는 Objective-C 기반의 NSNetServices API 를 사용해야 합니다.

이러한 API 들은 [NSNetServices and CFNetServices Programming Guide] 에 설명되어 있습니다. 이러한 API 의 CFNetwork 과 Foundation 형식에 대해 각각  [CFNetServices Reference] and [NSNetService Class Reference] 을 읽어 주시기 바랍니다.

역자주: 제가 아직 개발을 시작하지 않아서, 위에서 네트웍 서비스를 discover, register 한다는 의미가 크게 와닿지를 않네요. 오역이 안되었기를 바라며, 혹시 오역이라면 댓글 부탁합니다.

2010년 2월 27일 00:16 경부고속도로 아래에서..



출처 : http://blog.naver.com/PostView.nhn?blogId=dontbeshy&logNo=90082142378
Posted by 오늘마감

댓글을 달아 주세요