2013 이전/iOS개발

[iOS 개발] iCloud app 연동 설정

hagulu 하구루2017. 2. 25. 16:19

앱내의 셋팅 기능에서 많이 사용할 수 있는 간단한 iCould 연동을 소개 해보겠다.


오늘 포스팅할내용은 iCloud 연동을 위한 기본적인 설정 방법에대해서 알아 본다.

iCould를 앱에서 이용할수 있는 것은 아래와 그림과 같이 Document Storage와 keyValue Data Strorage 두종류 이다.






Document Storage는 직접 파일을 저장하고 이를 로드할수 있도록 사용이 가능하고, 사용자의 iCloud용량이 다 찰때까지 이용할 수 있다. 앱에 따른 제한은 없다.

keyValue Data Strorage는 간단하게 NSUserDefault와 비슷한 방식으로 사용이 가능하고, 1M와 1024개의 키로 제한이 있다.

좀더 자세한 정보를 원한다면 애플 공식 페이지 가이드
를 참고 하기 바란다.

이제 iCloud를 쓰기위한 준비단계부터 시작하겠다 일단 먼저 App ID 설정에서 iCloud를 활성화 해주어야 한다.
developer 페이지에서 Provisioning Portal 메뉴의 App IDs 메뉴로 가서 해당하는 app ID 에 위에 보는것처럼 iCloud가 Enabled되도록 configure를 수정해 주어야 한다.




해당하는 내용을 수정을 하였으면 적용이 되어 있는 Provisioning 파일도 새로 받아서 이를 이용해서 개발해야 한다.

이제 프로젝트에 추가를 해주어야 한다.

먼저 해당 Targets 의 Summary의 Entitlements 항목을 아래와 같이 수정해 주어야 한다.






 위와 같이 해당 사항을 체크해주고

iCloud에서 이용될 id를 만들어 주어야 한다.

여기서 id가 중요한데, 유니버셜 앱의 경우 상관이 없지만,
따로 배포되는 lite 버젼의 앱이나, 아이폰과 아이패드 가 다른 앱으로 배포 되는경우
각각의 bundle ID와 같은 id를 사용하면 이를 이용해 싱크를 할수가 없다.

그렇기 때문에 여기에 사용되는 ID는 iCloud로 싱크될 모든 앱들이 같은 ID를 이용해야 한다.

그리고 위에서 iCloud를 설정한 App ID와도 호환이 되어야 한다.

어떤 개발이든 설정이 가장 많은 말썽을 부리니 차근차근 확인해가면서 설정해나가기를 바란다.




이를 셋팅하면 자동으로 entitlemments 파일이 생성되고 내용이 적용된다.

이로써 기본적인 설정은 모두 마쳤다.

여기 까지 하고 앱이 디바이스로 올라가면 제대로 진행되것이다.

그외에 에러가 발생한다면, App ID 와 프로파일등의 문제일 수 있으니 처음 부터 차근차근 확인해 보기 바란다.


다음에는 간단하게 keyValue Data Strorage 를 이용한 iCloud 에대해서 포스팅 해보겠다.



댓글

댓글쓰기 폼

2013 이전/iOS개발

[iOS 개발] NSArray 역순으로 변환

hagulu 하구루2017. 2. 25. 16:16

NSArray의 Value들을 역순으로 정렬할때 다음과 같이 하면된다.

 
[[array reverseObjectEnumerator] allObjects]
reverseObjectEnumerator 라는 메소드를 통해서 역순이 된 array의 NSEnumerator 객체를 얻게 되고
여기서 부터 allObjects를 통해서 해당 array를 얻게 된다.


댓글

댓글쓰기 폼

2013 이전/iOS개발

[iPhone 개발] string 이 URL 형식인지 확인하기

hagulu 하구루2017. 2. 25. 16:08

어떤 string이 url인지 판별하는 방법은 여러가지가 있다.

 
하지만 대부분 http 와 같은 프로토콜을 꼭 포함 시켜야 하거나,
"adf.asdf.asdf" 등의 실제로 사용가능한 주소 형식이 아니더라도 주소로 판별되는 경우가 있다.
그래서 좀더 정확성 높은 방법을 찾다가
정규 표현식을 통한 방법 중에 괜찮은 방법을 찾앗고,  
여기에도 문제점이 있어서 수정해서 아래와 같이 사용해 보았다.

NSString *ptn = @"(((http|https)://)?([0-9a-z_-]+\\.)+(aero|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel|ac|ad|ae|af|
ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|
cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cx|cy|cz|cz|de|dj|dk|dm|do|dz|ec|ee|eg|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|
gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|
jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mn|mn|mo|
mp|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|nom|pa|pe|pf|pg|ph|pk|pl|pm|pn|
pr|ps|pt|pw|py|qa|re|ra|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sj|sk|sl|sm|sn|so|sr|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|
tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw|arpa)
($|((:[0-9]+)?((\\/([~0-9a-zA-Z\\#\\+\\%@\\.\\/_-]+))?(\\?[0-9a-zA-Z\\+\\%@\\/&\\[\\];=_-]+)?)?)))";
    
NSRange range = [aStr rangeOfString:ptn options:NSRegularExpressionSearch];

위 정규 표현식의 중점은 .com .net 과 같은 정의되어 있는 것들만 포함이 되는것을 찾는것이다.
 보기 좋게 하기 위해 개행을 하였습니다. 사용할때는 개행을 제거하고 이용하시기 바랍니다.


댓글

댓글쓰기 폼

2013 이전/iOS개발

[iPhone 개발] AudioSessionAddPropertyListener 의 해제

hagulu 하구루2017. 2. 25. 16:08

audio session 을 사용하다보면


AudioSessionAddPropertyListener 를 통해서  리스너를 등록해서 사용하게 되는데,

이 리스너는 해제해주지 않으면 계속 해당 프로퍼티에 대해서 리스너를 유지하고 있다.

리스너를 등록한 객체가 release 되더라도, 리스너는 해제되지 않는다. 


명시적으로 해지를 해주어야 하는데



AudioSessionRemovePropertyListenerWithUserData

위 함수를 통해서 해제를 해주어야 한다.


AudioSessionAddPropertyListener 은 계속 추가되는 방식이기 때문에 콜백 함수대신에 NULL을 넣는 등의 방식으로는 해제가 되지 않고 위에 소개된 메소드를 통해서만 해지가 가능하다. 


사용법은 AudioSessionAddPropertyListener 와 모두 같은 파라미터를 넣어주면 된다.

AudioSessionAddPropertyListener를 사용할 수 있다면 쉽게 사용할 수 있을 것이다.


댓글

댓글쓰기 폼

2013 이전/iOS개발

[iPhone 개발] sqlite query 따옴표 처리

hagulu 하구루2017. 2. 25. 16:08

sqlite 를 이용해서 쿼리를 사용하다 보면 쿼리에서 스트링을 넣을때


SELECT TEST FROM TEST_TABLE WHERE TEST = 'string'

와 같이 따옴표 안에 string을 넣게 된다.

그런데 스트링에 따옴표를 추가하고 싶으면 어떻해야 할까?

당연히 \' 라고 생각을해서 스트링을 변환을 했더니 되지 않았다.

db를 잘 아시는 분들에게는 쉬운 답이겠지만, 찾아 보니 따옴표를 두개를 넣어 줘야 한다.

즉 'string' 이라는 string을 입력하고 싶으면


SELECT TEST FROM TEST_TABLE WHERE TEST = '''string'''

와 같이 처리해 주어야 한다.

 '''string'''

쌍따옴표가 아니라 모두 홑따옴표 입니다.


댓글

댓글쓰기 폼

2013 이전/iOS개발

[iPhone 개발] audiosession category 의 비밀

hagulu 하구루2017. 2. 25. 16:07

사운드를 나오게 하는 앱을 개발하다 보면

여러 sound와 관련된 문제에 봉착하게 되는데
여기에는 audiosession이 가지고있는  category에 기인하는 경우가 많다.

여기서 먼저 다루어볼 부분은 route 부분이다.
현재 iphone audiosession 에는
다음과 같은 category가 있다.
AVAudioSessionCategoryAmbient;
AVAudioSessionCategorySoloAmbient;
AVAudioSessionCategoryPlayback;
AVAudioSessionCategoryRecord;
AVAudioSessionCategoryPlayAndRecord;
AVAudioSessionCategoryAudioProcessing;
각각에 대한 좀더 구체적인 설명은 아래 링크를 참조 하기 바란다.
위에 링크에 나와 있는 특성에 따라 output route의 처리도 달라지는데 이 정의를 제대로 알지 못해서 고생을 했었다.
위 category중에서 output이 가능한것은
AVAudioSessionCategoryAmbient;
AVAudioSessionCategorySoloAmbient;
AVAudioSessionCategoryPlayback;
AVAudioSessionCategoryPlayAndRecord;
위 네가지 이다.
이때 소리가 기본적으로 speaker 로 소리가 나는것은
AVAudioSessionCategoryAmbient;
AVAudioSessionCategorySoloAmbient;
AVAudioSessionCategoryPlayback;
이고,
기본적으로 ear speaker를 통해서 소리가 나오는것은

AVAudioSessionCategoryPlayAndRecord;

이다.
ear speaker를 통해 음원을 재생해야 한다면 위 세가지를 통해서는 불가능하다 (내가 찾아본 범위 안에서)
일반적으로 음원이 재생되는 route를 변경하기 위해서는

        UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
        AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,sizeof (audioRouteOverride),&audioRouteOverride);

        UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_None;
        AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,sizeof (audioRouteOverride),&audioRouteOverride);

와 같은 방식으로 변경을 하게 되는데

kAudioSessionProperty_OverrideAudioRoute 에 set할수 있는 값은

kAudioSessionOverrideAudioRoute_None - 기본 재생 route

kAudioSessionOverrideAudioRoute_Speaker - speaker 
요 두가지 뿐이다.
그렇기 때문에 기본 재생이 speaker 인 위의 세가지를 통해서는 위 방법을 통해서 route를 바꿀수 있는 방법은 없다.
즉, voip와 같은 ear speaker 를 통해 기본적으로 소리가 나야 하는  앱을 만들기 위해서는  AVAudioSessionCategoryPlayAndRecord 를 꼭 이용해야 한다.


너무 당연한 답을 길게 쓴게 아닌가 갑자기 민망해 지려고 한다;;; ;


나 같이 헤매고 있는 어떠한 분에게 도움이 되었으면 한다.


댓글

댓글쓰기 폼

2013 이전/iOS개발

[iPhone 개발] keyboard 애니메이션 정보 얻기

hagulu 하구루2017. 2. 25. 16:06

키보드에 붙어 다니는 뷰를 만들다 보니 keyboard 가 가지고 있는 애니메이션과 동일하게 해당뷰의 애니메이션을 지정해주어야 한다.

예전 iOS4 까지는

[UIView setAnimationDuration:0.3];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
위와 같은 애니메이션을 주면 키보드와 혼연일체로 움직인다.

하지만 iOS5 로 업데이트 되면서 keyboard 가 빨라 졌다.

테스트를 통해서 확인해 본결과 duration이 0.26으로 줄어 들었다.

게다가 iOS5에는 일본어 키보드에 힌트를 위한 뷰가 키보드위에 생겨났다.

이에 관한 것은 http://hagulu.com/129 포스트를 참고 하길 바란다.

일본어 키보드 때문에 대응해야하는 애니메이션이 있는데,

기존에 다른 언어 키보드가 있을때 일본어 키보드로 변경될때는  애니메이션이 없이 움직인다.

따라서 키보드 위에 붙어 다니는 뷰에서 애니메이션이 없어야 한다.

일본어 키보드가 뜨면 키보드 위에 붙어있는 뷰가 애니메이션이 적용되어 부자연스럽게 보여진다.

이렇게 iOS4 이전과 iOS5 이후를 if문 없이 대응 할수 있는 방법을 설명하려고 한다.

위에 소개된 포스트에서 이용하던 것과 비슷한 방법이다.

먼저 아래에 두개의 notification을 설정해 준다.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];

해당 notification은 보시는 봐와 같이 키보드가 나타나거나 사라지려 할때 나타나는 notification 이다.

이때에 notification 이 가지고 있는 정보를 통해서 간단하게 해당 키보드의 애니메이션 정보를 가져올수 있다.

- (void)keyboardWillShow:(NSNotification *)notification {
    NSLog(@"keyboard will show");
   
    NSTimeInterval keyboardAnimationDuration;
    UIViewAnimationCurve keyBroadAnimationNumber;

    NSValue* value = [notification.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];
    [value getValue:&keyboardAnimationDuration];
    
    value = [notification.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey];
    [value getValue:&keyBroadAnimationNumber];
    
}

- (void)keyboardWillHide:(NSNotification *)notification {
    NSLog(@"keyboard will hide");
   
    NSTimeInterval keyboardAnimationDuration;
    UIViewAnimationCurve keyBroadAnimationNumber;

    NSValue* value = [notification.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];
    [value getValue:&keyboardAnimationDuration];
    
    value = [notification.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey];
    [value getValue:&keyBroadAnimationNumber];
}
위와 같이 UIKeyboardAnimationDurationUserInfoKey와 UIKeyboardAnimationCurveUserInfoKey를 통해서 애니메이션 시간과 애니메이션 curve 정보를 얻어 올수 있고 이를 통해서 키보드가 나타날때와 사라질때 뷰를 관리해주면 키보드와 혼연일체로 움직이는것을 확인해 볼수 있을것이다.
 


댓글

댓글쓰기 폼

2013 이전/iOS개발

[iPhone 개발] mov 파일 mp4로 변환하기

hagulu 하구루2017. 2. 25. 16:06

안드로이드와 호환이 되는 파일 전송을 구현하다 보니 동영상 전송에 문제가 발생했다.

 
일반적으로 아이폰 비디오 레코더를 이용을 하게되면,
mov라를 확장자의 quickTimeMovie라는 방식으로 저장이 되어 진다.
이 파일을 그대로 안드로이드에 전송을 했더니
안드로이드에서는 하드웨어 코덱을 통해서는 재생을 할수가 없었다.
quick time movie 와  mpeg-4는 외부 포멧만 다를뿐 내부의 영상과 음성 코덱은 유사하다.
따라서 빠르게 변환이 가능한 방법이 있지 않을까 하고 찾다가 방법을 찾게 되었다.
바로 iOS 4 부터 지원되는 AssetLibrary를 이용하는 방법이다
이를 통해서 아래와 같이 구현해 보았다.
변환을 원하는 파일의 NSURL 과 저장을 원하는 파일 path의 NSString 을 주면 해당 path에 저장이 되게 된다.
+ (void) convertVideoQtimeToMpeg4:(NSURL *) videoURL withPath:(NSString *)videoPath {
    AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:videoURL options:nil];
    
    NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset];

    if ([compatiblePresets containsObject:AVAssetExportPresetLowQuality]) {
        AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:avAsset presetName:AVAssetExportPresetPassthrough];
        
        exportSession.outputURL = [NSURL fileURLWithPath:videoPath];
        
        exportSession.outputFileType = AVFileTypeMPEG4;
        
        CMTime start = CMTimeMakeWithSeconds(0.0, 600);
        
        CMTimeRange range = CMTimeRangeMake(start, [avAsset duration]);
        
        exportSession.timeRange = range;
        
        [exportSession exportAsynchronouslyWithCompletionHandler:^{
            
            switch ([exportSession status]) {
                    
                case AVAssetExportSessionStatusFailed:
                    NSLog(@"Export failed: %@", [[exportSession error] localizedDescription]);
                    break;

               case AVAssetExportSessionStatusCompleted:
                     NSLog(@"Export Success");
                     break;
                    
                case AVAssetExportSessionStatusCancelled:
                    
                    NSLog(@"Export canceled");
                    
                    break;
                    
                default:
                    
                    break;
                    
            }
            
            [exportSession release];
            
        }];
        
    }
}

이 중에서 초기화 부분이 중요한데 presetName 에
아래처럼 AVAssetExportPresetPassthrough 를 지정해 주어야 다른 포멧으로 변환이 가능하다
 
[[AVAssetExportSession alloc]initWithAsset:avAsset presetName:AVAssetExportPresetPassthrough];
아래와 같이 AVAssetExportPresetMediumQuality 와 같은 파라미터를 주고 outputFileType를 AVFileTypeMPEG로 주게 되면 SIGNAL ABORT가 발생하고 죽게 된다.
 
 AVAssetExportSession *exportSession  = [[AVAssetExportSession alloc]initWithAsset:avAsset AVAssetExportPresetMediumQuality];

exportSession.outputFileType = AVFileTypeMPEG4;
해당 AVAssetExportSession 의 지원되는 output 포멧을 확인하고 싶을때는 AVAssetExportSession 의 supportedFileTypes propert를 통해서 확인해 볼 수가 있다.


추가로 유의 할 것은 이 방식은 asynchronous 이다.

그렇기 때문에 위와 같이 변환을 한 이후에 바로 이를 이용할수 있는것이 아니다
 [exportSession exportAsynchronouslyWithCompletionHandler:^{
            
            switch ([exportSession status]) {
                    
                case AVAssetExportSessionStatusFailed:
                    NSLog(@"Export failed: %@", [[exportSession error] localizedDescription]);
                    break;

               case AVAssetExportSessionStatusCompleted:
                     NSLog(@"Export Success");
                     break;
                    
                case AVAssetExportSessionStatusCancelled:
                    
                    NSLog(@"Export canceled");
                    
                    break;
                    
                default:
                    
                    break;
                    
            }
            
            [exportSession release];
            
        }];

당황하지 않길 바란다 이 소스는 위에 있는 전체 소스의 일부분이다. 

따라서 위 소스와 같이 exportAsynchronouslyWithCompletionHandler 를 등록하여 "AVAssetExportSessionStatusCompleted"를 확인해야 한다.

이를 꼭 유의해서 사용하기 바란다.


댓글

댓글쓰기 폼

2013 이전/iOS개발

[iPhone 개발] UIView 에 간단한 이벤트 적용하기

hagulu 하구루2017. 2. 25. 16:05

Button이 아닌 일반 UIView에 각종 터치 체스췌를 등록하는 방법이다.

iOS sdk4.0부터 지원되는것으로 알고 있다.
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapPiece:)];
[piece addGestureRecognizer:tapGesture];
[tapGesture release], tapGesture = nil;
UITapGestureRecognizer 를 만들고 액션을 지정해주면 된다.

그리고 해당 뷰에 addGestureRecognizer 를통해 등록을 해주면 해당 view에 이벤트를 등록해 줄수 있다.


UIPanGestureRecognizer
UILongPressGestureRecognizer

위처럼 Tab이외에도 여러 이벤트가 있고 잘 활용하면 편하게 이벤트를 관리 할수 있을것이다

댓글

댓글쓰기 폼

2013 이전/iOS개발

[iPhone 개발] CGImage의 Orientation

hagulu 하구루2017. 2. 25. 16:05

UIImage 의 CGImage를  Quartz 2D를 통해 그리다 보면 UIImage를 통해서 그릴때와 다르게

Orientation이 제대로 적용이 안되게 될것이다.
섬네일을 만들기 위해서 이미지를 일정 크기로 축소를 하다가 발견한 것인데,
 
UIImage에는 imageOrientation라는  property orientation 정보가 들어 있고, 그 정보를 통해서 CGImage를 회전하여 보여주게된다.
즉, CGImage 자체는 Orientation이 적용되지 않은 순수한 이미지 정보인것이다.
때문에 CGImage를 이용할때 UIImage의 imageOrientation정보를 이용해 변경 해야한다.
imageOrientaion의 데이터 형은 다음과 같다 .
typedef enum {
   UIImageOrientationUp,
   UIImageOrientationDown,   // 180 deg rotation
   UIImageOrientationLeft,   // 90 deg CCW
   UIImageOrientationRight,   // 90 deg CW
   UIImageOrientationUpMirrored,    // as above but image mirrored along
   // other axis. horizontal flip
   UIImageOrientationDownMirrored,  // horizontal flip
   UIImageOrientationLeftMirrored,  // vertical flip
   UIImageOrientationRightMirrored, // vertical flip
} UIImageOrientation;

그리고 다음은 본인이 이용하기위해 UIImage와 줄이려는 이미지 사이즈를 통해 orientation이 적용된 CGImage로 만들어진 순수한 UIImage를 리턴하는 메소드 이다.

-(UIImage*) imageWithOrientationInCGImage:(UIImage* )image withSize:(CGSize)imageNewSize{
    
    UIImageOrientation imageOrientation = image.imageOrientation;
    
    UIImage* resultImage;
    UIGraphicsBeginImageContext(CGSizeMake(imageNewSize.width, imageNewSize.height));
    CGContextRef context = UIGraphicsGetCurrentContext();
    switch (imageOrientation) {
        case  UIImageOrientationUp:
            CGContextTranslateCTM(context, 0, imageNewSize.height);
            CGContextScaleCTM(context, 1.0, -1.0);
            CGContextDrawImage(context, CGRectMake(0, 0, imageNewSize.width, imageNewSize.height), image.CGImage);
            break;
        case UIImageOrientationDown:
            CGContextDrawImage(context, CGRectMake(0, 0, imageNewSize.width, imageNewSize.height), image.CGImage);
            break;
        case UIImageOrientationLeft:
            CGContextTranslateCTM(context, imageNewSize.width, 0);
            CGContextScaleCTM(context, -1.0, 1.0);
            CGContextTranslateCTM(context, 0, imageNewSize.height);
            CGContextRotateCTM (context, -90 * M_PI / 180);
            CGContextDrawImage(context, CGRectMake(0, 0, imageNewSize.height, imageNewSize.width), image.CGImage);
            break;
        case UIImageOrientationRight:
            CGContextTranslateCTM(context, imageNewSize.width, 0);
            CGContextScaleCTM(context, -1.0, 1.0);
            CGContextTranslateCTM(context, imageNewSize.width, 0);
            CGContextRotateCTM (context, 90 * M_PI / 180);
            CGContextDrawImage(context, CGRectMake(0, 0, imageNewSize.height, imageNewSize.width), image.CGImage);
            break;
        default:
            
            break;
    }

    resultImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return resultImage;
}

UIImage에 있는 imageOrientation을 확인해서 CGImage를 변경하여 새로운 UIImage에 넣어주는 방식이다.

댓글

댓글쓰기 폼

hagulu.com

.....

VISITED

Today : 0

Total : 180,227

Lately Comment