멍멍이네 블로그

지금 Facebook API를 사용하기 위해서 developer.facebook.com에서 파일을 설치 했는데... FacebookSDK.framework 파일이 없음..


다른 블로그나 유튜브 동영상 같은 곳은 설치 하면 바로 생길거라는데.. 왜 나만 없지? 하고 찾아보던 도중


Android때와 같은 글을 발견했다.


SDK for iOS 다운받는곳에서 밑 부분을 보면 Android때와 마찬가지로




Bolt, 타겟 네트워크 및 Facebook 프레임워크가 포함된

3.18버전입니다. 변경 로그 또는 업그레이드 가이드를 참조하세요.




라는 글이 보인다..

그래... FacebookSDK.framework가 포함된 버전은 3.18버전인것이다!!!


최신버전 다운받지 말고, 3.18버전을 다운 받을 경우 FacebookSDK.frameowrk 파일이 생긴다!



원인 : SDK설치 시 FacebookSDK.framework 파일이 안생김..


해결방법 : SDK를 3.18버전 설치!


 

 

 

Unable to verify assembly data; you must provide an authorization key when loading this assembly.
UnityEngine.Security:LoadAndVerifyAssembly(Byte[])
c__Iterator0:MoveNext() (at Assets/Plugins/Facebook/Scripts/FB.cs:423)

Could not securely load assembly from https://integrated-plugin-canvas-rsrc.fbsbx.com/rsrc/unity/lib/sdk_6.2/CanvasFacebook.dll
UnityEngine.Debug:LogError(Object)
FbDebug:Error(String)
c__Iterator0:MoveNext() (at Assets/Plugins/Facebook/Scripts/FB.cs:427)

 

 

원인

- 처음 Unity3D에서 FacebookAPI를 다운받아서 사용하려고 하는데 위와 같은 에러가 뜸.

 

해결방법(Unity3D 5.1버전대 / 페이스북 (140825일자 버전 사용)

- FB.cs파일에서 411번째 줄 정도에

  #if UNITY_4_5  -> #if UNITY_4_5 || UNITY_4_6 || UNITY_5_0 || UNITY_5_1 으로 수정함.

종료상태일 경우 didFinishLaunchingWithOptions 메서드 내에 launchOptions 파라미터에 push 내용이 들어가게 됩니다.
거기에서 push 내용을 파싱해서 URL을 추출한 뒤 이동하는 메서드를 구현하시면 되겠네요.

 

출처 : http://cafe.naver.com/mcbugi/320619

유니티로 프로젝트를 진행하다가 간혹 드로우콜(Draw Call)에 관한 문제를 많이 겪는다. - 특히나 모바일 같은 경우 -

 

PC기반은 어느정도 사양에 의해 커버가 돼는데 - 그런데도 발생하기도 함.. 극한으로 최적화를 안하거나 드로우콜을 낭비할 경우 - 모바일은 사양이 좋아졌다지만, 아직 한참 부족한 상태다 - PC처럼 최적화없이 낭비할 경우 커버가 안됀다 -

 

 

서론은 이쯤 하고, 본론으로 들어가면

 

일단 드로우 콜(Draw Call)이란 무엇일까?

CPU가 그래픽 API를 호출해서 GPU에게 렌더링을 요청하는 것을 말합니다.
이 작업은 자원이 많이 들기 때문에 드로우 콜을 줄이는 것이 성능 향상에 있어 매우 중요합니다.
스프라이트들을 스프라이트 시트에 모두 모아놓으면 단 한번의 드로우 콜로 모든 스프라이트를 화면에 표시할 수 있습니다. 게임에 사용하는 스프라이트가 많을수록 성능이 획기적으로 향상 됩니다.
(출처 : http://blog.daum.net/yy.kim.0410/278)

 

드로우 콜이란 화면에서 얼마나 많은 이미지를 뿌려주는 가에 관해 드로우 콜의 수가 늘어난다

유니티에서 많은 이미지를 낭비하게 되면 그만큼 개발프로그램에서 부담이 가는 부분이기 때문에 최적화 및 드로우콜 수의 감소는 선택이 아닌 필수이다.

 

가장 좋은방법으로는 이미지의 수를 줄이는 것.

애초에 이미지 수를 줄여서 드로우콜을 줄이면 가장 좋지만, 그것이 안되는 경우가 대다수.

 

그 다음 방법으로는 이미지의 아틀라스화 이다.

이미지 아틀라스화의 장단점은 직접 찾아보면 금방 나옵니다.

간단하게 설명하자면 장점은 드로우콜의 수를 쉽게 줄일 수 있다.

여러 이미지를 압축하는 방식이기 때문이다.

 

단점 역시 간단하게 말하자면 이미지 관리가 철저해야됀다는것이다.

이미지를 압축해서 사용하는 영역을 침범하면 안되고, 겹픽셀 같은 경우 간혹 발생하는경우도 있고 - NGUI 아틀라스 사용 시 생기는 문제 -

이미지 낭비가 생기는 경우도 없잖아 있다 - 아틀라스는 대게 이미지가 사각형이며 2의 배수이다. 500x500의 4장을 합치면 2000x 2000이 아니라 2048x2048이 되기 때문에 많은 메모리가 필요 이상으로 이용된다.

 

그밖에 자세한 글은 구글링 외 다른 곳에서 참조하시고, 제 글은 간단하게나마 이렇구나 정도로 읽어주시면 됍니다 ㅎ

 

p.s.

저는 NGUI를 이용해서 아틀라스화 할 때 생기는 문제들이였고, 이미지패커? 라는 기능이 프로버전에 지원하는 것 같더군요.

틀리거나 지적사항 및 수정사항에 대해서 댓글 부탁드립니다.

Unity - iOS 접근 플러그인 방법

 

제목 : Unity for IOS_Screen Capture한 이미지 카메라롤 에 등록하기.

 

Explan.

IOS에서 Application.CaptureScreenShot(path) 메소드를 사용할경우
캡처는 진행되나 해당 app 의 document폴더로 들어가서 카메라 롤에서 확인할수가 없다.
이를 등록해주는 방법 포스팅.


CaptureHelper.h

#import <Foundation/Foundation.h>

@interface CaptureHelper : NSObject

+(CaptureHelper *)sharedInstancs;

@end
CaptureHelper.mm
#import "CaptureHelper.h"

static CaptureHelper * captureHelper = [CaptureHelper sharedInstancs];

@implementation CaptureHelper : NSObject

+ (void)initialize{
    if(captureHelper == nil)
        captureHelper = [[CaptureHelper alloc] init];
}

+ (CaptureHelper *)sharedInstancs{
    return captureHelper;
}

- (id)init{
    if(captureHelper != nil){
        return  captureHelper;
    }
    
    self = [super init];
    if(self){
        captureHelper = self;
    }
    
    return self;
}


- (NSString *)getDocumentDirectory {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    
    return [paths objectAtIndex:0];
}

@end

extern "C"{
    void CaptureToCameraRoll(const char *fileName)
    {
        NSString *file = [NSString stringWithUTF8String:(fileName)];
        NSString *filePath = [[captureHelper getDocumentDirectory] stringByAppendingString:file];
        UIImage *image = [[UIImage alloc] initWithContentsOfFile:filePath];
        
        UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
    }
}

위 2개의 파일을 생성후 Plugin/IOS 폴더에 위치 그후

how to used.

[DllImport("__Internal")]
public static extern void CaptureToCameraRoll(String fileName);

// 그이후 스크린 캡처 진행시.

Application.CaptureScreenShot(path);
CaptureToCameraRoll(string.Format("/{0}",path));

이후 카메라롤에서 캡쳐된 이미지를 확인하실수 있다.

 

 

 

URL : http://gomlib.blogspot.kr/2014/10/unity-for-iosscreen-capture.html

 

------------------------------------------------------------------------------

 

제목 : [iOS] 이미지, 동영상을 카메라 롤에 저장

 

이미지

 
1
2
3
4
5
6
7
8
9
10
11
12
13
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
// 이미지를 카메라 롤에 저장
UIImageWriteToSavedPhotosAlbum(image, self,
@selector(image:didFinishSavingWithError:contextInfo:), nil);
 
// 저장한 이후에 실행 될 메소드
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
    if (error) {
        NSLog(@"error: %@", [error localizedDescription]);
    } else {
        NSLog(@"saved");
    }
}


동영상

?
1
2
3
4
5
6
7
8
9
10
11
12
13
NSURL *mediaUrl = [info objectForKey:UIImagePickerControllerMediaURL];
// 동영상을 카메라 롤에 저장
UISaveVideoAtPathToSavedPhotosAlbum([mediaUrl path], self,
@selector(video:didFinishSavingWithError:contextInfo:), nil);
 
// 저장한 이후에 실행 될 메소드
- (void)video:(NSString *)videoPath didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
    if (error) {
        NSLog(@"error: %@", [error localizedDescription]);
    } else {
        NSLog(@"saved");
    }
}

 

출처 URL : http://fra3il.tistory.com/66

 

--------------------------------------------------------------------------------------

 

-(void) GetImageFromAlbum {
    [self GetImage:UIImagePickerControllerSourceTypeSavedPhotosAlbum];
}

 

-(void) StartCameraImagePic {
    NSLog(@"StartCameraImagePic");
    [self GetImage:UIImagePickerControllerSourceTypeCamera];
}

 

-(void) GetImageFromCamera {
    BOOL cameraAvailableFlag = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];
    if (cameraAvailableFlag) {
        [self performSelector:@selector(StartCameraImagePic) withObject:nil afterDelay:0.9];
    }
}

 

-(void) GetImage: (UIImagePickerControllerSourceType )source {
    UIViewController *vc =  UnityGetGLViewController();
   
    if(_imagePicker == NULL) {
        _imagePicker = [[UIImagePickerController alloc] init];
        _imagePicker.delegate = self;

    }
   
    _imagePicker.sourceType = source;
   
    [vc presentViewController:_imagePicker animated:YES completion:nil];
}

 

-(void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    UIViewController *vc =  UnityGetGLViewController();
    [vc dismissViewControllerAnimated:YES completion:nil];
   
    // added video support
    NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType]; // get media type
    // if mediatype is video
    if (CFStringCompare ((__bridge CFStringRef) mediaType, kUTTypeMovie, 0) == kCFCompareEqualTo) {
        NSURL *videoUrl=(NSURL*)[info objectForKey:UIImagePickerControllerMediaURL];
        NSString *moviePath = [videoUrl path];
        UnitySendMessage("IOSCamera", "OnVideoPickedEvent", [ISNDataConvertor NSStringToChar:moviePath]);
    } else{
        // it must be an image
        UIImage *photo = [info objectForKey:UIImagePickerControllerOriginalImage];
        NSString *encodedImage = @"";
        if (photo == nil) {
            NSLog(@"no photo");
        } else {
            // NSLog(@"MaxImageSize: %i", [self MaxImageSize]);
            //  NSLog(@"photo.size.width: %f", photo.size.width);
           
            if(photo.size.width > [self MaxImageSize] || photo.size.height > [self MaxImageSize] ) {
                NSLog(@"resizing image");
                CGSize s = CGSizeMake([self MaxImageSize], [self MaxImageSize]);
               
                if(photo.size.width > photo.size.height) {
                    CGFloat new_height = [self MaxImageSize] / (photo.size.width / photo.size.height);
                    s.height = new_height;

                } else {
                    CGFloat new_width = [self MaxImageSize] / (photo.size.height / photo.size.width);
                    s.width = new_width;
                }
                             
                photo =   [ISNCamera imageWithImage:photo scaledToSize:s];
            }
           
            NSData *imageData = nil;
            NSLog(@"ImageCompressionRate: %f", [self ImageCompressionRate]);
            if([self encodingType] == 0) {
                imageData = UIImagePNGRepresentation(photo);
            } else {
                imageData = UIImageJPEGRepresentation(photo, [self ImageCompressionRate]);
            }
            encodedImage = [imageData base64Encoding];
        }
       
        UnitySendMessage("IOSCamera", "OnImagePickedEvent", [ISNDataConvertor NSStringToChar:encodedImage]);
    }
}

 

 

구글플레이 앱 다운로드 오류 194 가 떴다.


어떤 어플을 다운 받으려는데,오류코드 194번이 뜨면서 다운로드에 실패함.



https://support.google.com/googleplay/android-developer/troubleshooter/6169937?hl=ko&ref_topic=15868

URL로 가보면, 구글 개발자 콘솔 도움말쪽에서 검색해본것이다.


어플리케이션이 다운로드 실패 할 경우의 문제점으로,

1. 지원 국가 체크

2. 지원 기기 체크

해보라고 나와있다.



글쓴이는 인터넷을 검색해서, 

출처 : http://aromio.tistory.com/300

위 URL 방식대로 (환경설정 - 어플리케이션 관리자) 탭에 들어가서 "구글 플레이" 앱의 "데이터"와 "캐시"를 삭제한 후 "업데이트를 삭제"하고 핸드폰을 재부팅 후 어플을 깔려고 하니까 잘 됀다.


(글쓴이인 저는 밑의 방식대로 해결했지만, 혹시나 문제가 해결되지 않으면 위의 구글 개발자 콘솔 도움말 방식도 참조해보시는 것도 괜찮을 것 같습니다)

Conversion to Dalvik format failed with error 1 에러가 떳음

인터넷에 검색해보니,

 

원인 1.

  라이브러리 충돌.

 

해결 1.

  충돌 된 라이브러리 제거 후 Project-Clean 후 다시 실행.

 

 

원인 2.

  proguard 버전 문제.

 

해결 2.

  이곳에서 progurad 최신 버전(4.6)을 다운로드해서 설치된 Android SDK 에 교체하니 

  (구체적으로, proguard 최신 버전 중 bin 과 lib 디렉터리만 복사하여 \android-sdk\tools\proguard\ 의

       디렉터리들을 대체했습니다)

 

 

원인 3.(이번에 경험)

  다른 라이브러리 프로젝트(저는 FacebookSDK를 사용함)를 추가할 경우 파일이 문제가 있는지, 해당 에러가 뜸.

 

해결 3.

  새로 최신버전을 다운받아서 연결하니까 문제없이 됌(동일한 조건.)

 

 

 

원인, 해결 2의 출처 : http://www.androidpub.com/1778287

conversion to dalvik format failed

 

원인 : 라이브러리가 중복됌.

 

해결방법 : 중복됀 라이브러리 제거(libs폴더와 library 프로젝트를 Add한것이 중복돼는경우도 있음)

Installation error: INSTALL_FAILED_CONFLICTING_PROVIDER

Please check logcat output for more details.

Launch canceled!

 

 

 

페이스북에서 예제파일 다운받아서 사용 중 내 파일에 샘플 코드를 옮기고 실행했는데 에러가 뜸!

검색해보니 다음과 같은 결과가 나왔다

 

 

원인

  <provider> 태그의 android:authorities  때문에 생기는 오류라고 한다.

  android:authorities 값을 바꾸거나 지워야 한다!

 

해결

  나같은경우는 예제파일과 내 파일이 같은 값을 가지고 있었다.

  둘다 지우고 재실행하니 문제없이 실행됌!

{"error":{"message":"An active access token must be used to query information about the current user.","type":"OAuthException","code":2500}}

 

 

원인 및 해결방법

 

한꺼번에 해결해서 정확한 원인과 결과는 모른다.

다만 페이스북 디벨로퍼 홈페이지를 참조해도 알것이다.

가장 대표적인 에러라면서 글이 있다.

 

그 글을 해석해서 주요 내용을 보면 주로 권한에 관한 문제일것이다 라고 되어있다.

매니페스트에 프로바이더 추가하고, 퍼미션 주니까 잘 됀거같다.


<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

 

 

<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/app_id"/>
<provider android:authorities="com.facebook.app.NativeAppCallContentProvider(AppID)"
                  android:name="com.facebook.NativeAppCallContentProvider"
                  android:exported="true"/>

 

provider의 (AppID) 를 @string/app_id 값으로 바꿔줘야됌

ex) android:authorities="com.facebook.app.NativeAppCallContentProvider123456789123456"