출처 : http://theeye.pe.kr/538

Android상에서 웹뷰를 사용하면서 Javascript 인터페이스를 사용하여 웹과 네이티브 코드간에 통신을 할 수 있습니다. 하지만 Android 4.2부터는 정상적으로 동작하지 않고 오류가 발생하는것을 발견하였습니다. 다음은 오류를 확인할 수 있는 간단한 코드입니다.

this.webView.getSettings().setJavaScriptEnabled(true);
this.webView.setWebChromeClient(new WebChromeClient());
this.webView.addJavascriptInterface(new Object() {
   
public void handshake() {
       
Log.d("JS", "handshake no params");
   
}

   
public void handshake(String json) {
       
Log.d("JS", "handshake with params: " + json);
   
}
}, "Android");


Javascript에서는 다음과 같이 위의 handshake()를 호출할 수 있습니다.

Android.handshake();


하지만 logcat에 다음과 같은 오류가 발생합니다.

E/Web Console: Uncaught TypeError: Object [object Object] has no method 'handshake'

여기서 중요한점은 4.2 이전버전들에서는 매우 잘 동작하는 API라는것입니다. 확인해본 결과 4.2(API 17)부터 Javascript에서 접근하려는 메소드에는 어노테이션을 추가해주어야 하도록 변경되었습니다. [확인]

결과적으로 위의 코드는 다음과 같이 @JavascriptInterface를 추가해주면 정상적으로 동작합니다. 물론 빌드 타켓을 API 17이상으로 해줄 필요가 있습니다.

this.webView.getSettings().setJavaScriptEnabled(true);
this.webView.setWebChromeClient(new WebChromeClient());
this.webView.addJavascriptInterface(new Object() {
   
public void handshake() {
       
Log.d("JS", "handshake no params");
   
}

   
@JavascriptInterface
   
public void handshake(String json) {
       
Log.d("JS", "handshake with params: " + json);
   
}
}, "Android");



참고 : http://stackoverflow.com/questions/14031635/android-4-2-1-webview-and-javascript-interface-breaks

Posted by 모과이IT
,


출처 : http://cafe.naver.com/sunschool/4400


HttpClient의 HttpPost 메서드를 사용하여 로그인을 처리한 예제.

[실행결과]

로그인이 성공한 경우 화면                     로그인이 실패한 경우 화면

   

 

[login_layout.xml]

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/layout01"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     android:orientation="vertical"
     android:visibility="visible">
    <LinearLayout
         android:orientation="horizontal"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:gravity="center_horizontal">
        <TextView android:text="  아이디: "
             android:id="@+id/TextView02"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"/>
        <EditText android:text=""
             android:id="@+id/id"
             android:layout_width="200px"
             android:layout_height="wrap_content"/>
     </LinearLayout> 
     <LinearLayout
             android:orientation="horizontal"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:gravity="center_horizontal">
        <TextView android:text="패스워드: "
             android:id="@+id/TextView01"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"/>
       <EditText android:text=""
             android:id="@+id/passwd"
             android:layout_width="200px"
             android:layout_height="wrap_content"
             android:password="true"/>
      </LinearLayout> 
 <LinearLayout
      android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center_horizontal">
 <Button android:text="로그인"
  android:id="@+id/loginButton"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:gravity="center_horizontal"/>
    </LinearLayout> 
</LinearLayout>

 

[LoginActivity.java]

 

  package kim.android.test;

  import java.io.IOException;
  import java.io.InputStream;
  import java.io.InputStreamReader;
  import java.util.ArrayList;

  import org.apache.http.HttpEntity;
  import org.apache.http.HttpResponse;
  import org.apache.http.NameValuePair;
  import org.apache.http.client.ClientProtocolException;
  import org.apache.http.client.HttpClient;
  import org.apache.http.client.ResponseHandler;
  import org.apache.http.client.entity.UrlEncodedFormEntity;
  import org.apache.http.client.methods.HttpPost;
  import org.apache.http.impl.client.DefaultHttpClient;
  import org.apache.http.message.BasicNameValuePair;
  import org.apache.http.params.HttpConnectionParams;
  import org.apache.http.params.HttpParams;
  import org.xmlpull.v1.XmlPullParser;
  import org.xmlpull.v1.XmlPullParserFactory;

  import android.app.Activity;
  import android.app.ProgressDialog;
  import android.graphics.Color;
  import android.os.Bundle;
  import android.os.Handler;
  import android.os.Message;
  import android.util.Log;
  import android.view.View;
  import android.view.View.OnClickListener;
  import android.widget.Button;
  import android.widget.EditText;
  import android.widget.LinearLayout;
  import android.widget.Toast;

 

  public class LoginActivity extends Activity implements OnClickListener {
    private EditText id;
    private EditText passwd;
    private ProgressDialog pDialog;
    private LinearLayout layout01;
    private Button button;
 
 
   @Override
    protected void onCreate(Bundle savedInstanceState) {
     // TODO Auto-generated method stub
         super.onCreate(savedInstanceState);
         setContentView(R.layout.login_layout);
         id=(EditText)findViewById(R.id.id);
         passwd=(EditText)findViewById(R.id.passwd);
         button=(Button)findViewById(R.id.loginButton);
         button.setOnClickListener(this);
         layout01=(LinearLayout)findViewById(R.id.layout01); 
    }

 

   @Override
   public void onClick(View v) {
      // TODO Auto-generated method stub
      loginProcess();      //로그인 버튼이 클릭되면 로그인 처리를 시작한다.
    }
 

   // 네트웍 처리결과를 화면에 반영하기 위한 안드로이드 핸들러

   // responseHandler에 의해 처리된 결과가 success인 경우 바탕화면을 초록색으로 바꾸고

   // 로그인이 성공했다는 메시지를 토스트로 출력

   // 로그인이 실패한 경우 바탕화면을 빨강색으로 바꾸고 로그인실패 메시지를 토스트로 출력
   private final Handler handler = new Handler() {
      @Override
      public void handleMessage(Message msg) {
            pDialog.dismiss();
            String result=msg.getData().getString("RESULT");
            if ( result.equals("success") ) {
                  layout01.setBackgroundColor(Color.GREEN);
                  Toast.makeText(LoginActivity.this, "성공적으로 로그인하였습니다.",
                                         Toast.LENGTH_LONG).show() ;     
            } else {
                  layout01.setBackgroundColor(Color.RED);
                  Toast.makeText(LoginActivity.this, "로그인 실패",
                                         Toast.LENGTH_LONG),show() ;    
             }
       } 
    };
 

    //서버에서 전송된 XML 데이터를 파싱하기 위한 메서드

    //이 예제에서는 서버에서 로그인이 성공하는 경우(id=kim&passwd=111)하는 경우 <result>success</result>

    //실패하는 경우 <result>failed</result>를 반환하도록 설정해 두었다. 
    public String parsingData(InputStream input){
        String result=null;
        try {
             XmlPullParserFactory factory= XmlPullParserFactory.newInstance();
             XmlPullParser parser = factory.newPullParser();
             parser.setInput(new InputStreamReader(input));
             while ( parser.next() != XmlPullParser.END_DOCUMENT) {
                 String name=parser.getName();
                  if ( name != null && name.equals("result"))
                         result=parser.nextText();
              }
         }catch(Exception e){e.printStackTrace();}
         return result;
     }
 

    //로그인 버튼이 클릭되면 수행되는 메서드

    //  responseHandler는 Http요청에 대한 HttpResponse가 반환되면 결과를 처리하기 위한

     //  콜백메서드를 정의하고 있는 객체이다.

     //  Response를 받게 되면 parsingData()메서드를 호출하여 서버로 부터 받은 XML 파일을 처리하여

     // 그결과를 result 문자열로 반환받는다.

     // 이렇게 반환받은 result문자열을 화면에 반영하기위해 안드로이드UI핸들러인 handler를 통해 값을 전달한다.
    public void loginProcess() {
          final ResponseHandler<String> responseHandler=
               new ResponseHandler<String>() {

                 @Override
                 public String handleResponse(HttpResponse response)
                                                  throws ClientProtocolException, IOException {
                         String result=null;
                         HttpEntity entity=response.getEntity(); 
                         result=parsingData(entity.getContent());
                         Message message=handler.obtainMessage();
                         Bundle bundle=new Bundle();
                         if ( result.equals("success") )
                                      bundle.putString("RESULT", "success");
                         else
                                      bundle.putString("RESULT", "failed");
                         message.setData(bundle);
                         handler.sendMessage(message);
                         return result;
                 }
    };

 

     // 로그인이 처리되고 있다는 다이얼로그를 화면에 표시한다.
     pDialog=ProgressDialog.show(this, "", "로그인 처리중....");

 

     // 서버에 HTTP 처리 요청은 새로운 스레드를 생성하여 비동기식으로 처리하는것이 효율적이다.
     new Thread() {

           @Override
            public void run() {
                 String url = "http://192.168.10.2:8080/login.jsp";
                 HttpClient http = new DefaultHttpClient();
                 try { 
                     // 서버에 전달할 파라메터 세팅   
                     ArrayList<NameValuePair> nameValuePairs =
                                                              new ArrayList<NameValuePair>();
                     nameValuePairs.add(new BasicNameValuePair("id", id.getText().toString()));
                     nameValuePairs.add(new BasicNameValuePair("passwd", passwd.getText().toString()));
            

                   //     응답시간이 5초가 넘으면 timeout 처리하려면 아래 코드의 커맨트를 풀고 실행한다.
                   //     HttpParams params = http.getParams();
                   //     HttpConnectionParams.setConnectionTimeout(params, 5000);
                   //     HttpConnectionParams.setSoTimeout(params, 5000);

 

                  // HTTP를 통해 서버에 요청을 전달한다.

               // 요청에 대한결과는 responseHandler의 handleResponse()메서드가 호출되어 처리한다.

                  // 서버에 전달되는 파라메터값을 인코딩하기위해 UrlEncodedFormEntity() 메서드를 사용한다.

                  HttpPost httpPost = new HttpPost(url);
                  UrlEncodedFormEntity entityRequest =
                                       new UrlEncodedFormEntity(nameValuePairs, "UTF-8");
                  httpPost.setEntity(entityRequest);
                  http.execute(httpPost,responseHandler); 
                }catch(Exception e){e.printStackTrace();}
           }
      }.start();    //스레드를 실행시킨다.
 }

}

 

 

LoginActivity를 실행하기 위해 테스트서버를 만들었고, 테스트서버에는  로그인을 처리하기위한 login.jsp, 결과로 반환될 success.xml, failed.xml,을 다음과 같이 만들어 테스트 하였다. ㅎㅎ

 

 

[login.jsp]

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
   <% System.out.println("login.jsp가 호출됨");  %>
   <c:if test="${param.id=='kim'}" >
       <c:if test="${param.passwd=='111'}" >
            <jsp:forward page="success.xml"/>
       </c:if>
   </c:if>
   <jsp:forward page="failed.xml"/>
</body>
</html>

[success.xml]

<?xml version="1.0" encoding="UTF-8"?>
<result>success</result>

 

[failed.xml]

<?xml version="1.0" encoding="UTF-8"?>
<result>failed</result>

 

 

웹요청에 대한 처리결과를 html 로 받아서 화면에 브라우저를 이용하여 출력하게 하려면 WebView 위젯을 사용하면 간단하게 처리할수 있다.

WebView는 예제를 올려놓은 게시물이 있으니 그걸 참조 하면 될듯 ^^


Posted by 모과이IT
,
Objective-C Protocol(프로토콜) 심화
과니(tiny2n) 1:1 | 2013.02.14 09:58 | 조회 1,149
가가
Objective-C Protocol(프로토콜) 심화

통신상에서 Protocol이라 하면 통신규약이라 합니다. (이쯤되면 누구 나 다 알고있죠.)
Objective-C에서 Protocol은 Delegate라 합니다. (이쯤되면 누구나 알고 있죠.) 정말 ??!!? 하지만 이말은 100% 정답은 아닙니다. Protocol를 이용해 Delegate (Pattern)를 구현할 뿐, Protocol이 Delegate라 할 수는 없습니다. 그럼 프로토콜이 무엇이냐. 프로토콜은 다음과 같습니다.

Protocol = Interface

Objective-C상에서는 Interface(이하 인터페이스라)는 용어가 없고, Protocol (이하 프로토콜) 용어만 있어서 Objective-C (이하 오브젝티브 C)만 하셨던 분들은 위에 대한 정의가 없어 프로토콜을 델리게이트와 같은 것으로 생각하고 있는 경향이 큰 것 같습니다. 잘못된건 아니지만 100% 정답이라고 할 수 없습니다.

그럼 이제 인터페이스에 대해 알아야 겠죠. 인터페이스란 코드는 없고 메소드만 있는 것을 말합니다. 전에도 잠깐 설명한것 같은데 상속에는 크게 두가지 상속이 있습니다. 그 두가지란 클래스 상속과 인터페이스 상속입니다.
클래스 상속
is-a
인터페이스 상속
can-do

 코드 공유  코드 공유 안함
 다중 상속 지원 (몇 언어만 지원)  다중 상속 지원
* 다중 상속이 몇 언어만 지원하는 것은 다중상속은 복잡성과 결합도를 매우 증가하게 되어 유지보수를 어렵게 만들게 됩니다. 그래서 새로운 언어마다 다중상속을 지원하지 않는 추세 입니다.

설계를 하다보면 복수개의 다양한 성질이 유사성을 지닌다면, 상속(다향성)으로 이를 통일하는 것이 효율적입니다. 그렇지 않다면 객체에 따라 조건문을 통해서 분기할 수 밖에 없습니다. 이러한 조건문들은 변화에 민감하기 때문에 유지보수가 어려워집니다.
(객체지향 언어는 조건문을 최소화 하는 것이 핵심)

인터페이스 상속은 진정한 의미에 다중 상속은 아닙니다. 다중 상속이란 부모가 갖고 있는 상태 및 행위를 모두 갖는 것인데, 인터페이스에는 상태는 없고 행위만 있으므로 다중 상속이 아닌 인터페이스 위임(기능 부여)라 할 수 있습니다.

OOP에 핵심중에 다음 말이 있습니다.
"구현보다는 인터페이스에 맞춰서 코딩 하라"

전 시간에도 예기했지만, 클래스 상속은 클래스간에 결합도를 높여 유연한 설계를 하기 어렵게 만듭니다. 하지만 인터페이스 상속은 구현이 결합되어 있지않아 느슨한 커플링으로 유연한 설계를 가능하게 합니다.

하지만 가장 어려운 것은 어떤 상황에서 클래스 상속을 사용하고 어느 상황에서 인터페이스 상속을 해야 하는 가 입니다.
(설계시 가장 어려운 난제 입니다. 1. 베이스 클래스에서 추상 메소드를 만들어 파생 클래스에서 재정의 해야 할지, 2. 인터페이스에 선언하여 상속하여 구현해야 할지)

아래 예제로 어느 상황에서 클래스 상속과 인터페이스 상속이 쓰여야 하는지 설명하겠습니다.
(올바른 설계는 아니지만, 항상 예제를 만드는 것이 가장 어려운 관계로...)




한국인, 일본인, 외국인 모두 인간이므로 인간을 베이스 클래스로 각각 파생 합니다.


여기서 한국사람이지만 일본어를 하는 재일교포, 한국사람이지만 영어를 하는 재미교포를 넣어달라는 요구사항이 생겼다고 합시다.

  잉??
정말 누가봐도 올바른 설계가 아니죠. 깨지기 쉬운 설계입니다.

지금부터 클래스 상속과 인터페이스 상속이 어떻게 다른가 설명하고 위 예제를 어떻게 변경해야 하는지 알아보겠습니다.


클래스 상속은 "선천성 성질"을 나타내고,
인터페이스 상속은 "후천성 성질"을 타나냅니다.

선천성 성질 : 태어났을 때부터 갖고 있는 개체의 고유한 특성입니다. 인간은 모두 "먹기"와 "자기"는 태어났을 때 부여 받는 고유한 특징입니다.
후천성 성질 : 자라면서 환경에 따라 부여받을 수 있는 기능을 추가로 부여 받는 것입니다.

위에 제시된 선천성 성질과 후천성 성질을 구분하여 클래스 상속과 인터페이스 상속을 이용하여 클래스를 설계하면 다음과 같습니다.





인터페이스 in 오브젝티브 C

그럼 이번에는 오브젝티브C 안에서의 인터페이스가 어떻게 쓰여졌나 알아보겠습니다.

서두에도 얘기했지만 오브젝티브 C에서는 인터페이스라는 말이 프로토콜이라는 말로 쓰입니다. 클래스간에 규약이라고도 하지만 사실 위와 같이 기능 부여 라는 의미가 맞습니다. (맞다 틀리다 이분화 하는 것은 아닙니다.)

예제 1.
@interface AViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>

:  "선천적 성질"은 UIViewController를 따르며, "후천적 성질"은 UITableViewDelegate, UITableViewDataSource를 따릅니다.
다시말해 고유한 특성은 UIViewController 이지만, UITableViewDelegate, UITableViewDataSource의 기능을 부여합니다.

예제 2.
@interface AView : UIView <NSCopying>

: "선천적 성질"은 UIView를 따르며, "후천적 성질"은 NSCopying를 따릅니다.
다시 말해 고유한 특성은 UIView 이지만, NSCopying 기능인 깊은 복사 기능을 부여합니다. 


꼭 선언만이 아닌 구현코드에서도 인터페이스 중심으로 코딩할 수 있습니다. 다음은 제가 지금 제작하고 있는 프로젝트의 일부분 입니다.
/**
 패킷을 설정하는 메소드
 해당 패킷을 파싱하여 갯수 및 총금액을 계산
 @param SSIPacket SSIPacketPossessList
 */
- (void)setPacket:(id <SSIPacketList>)packet
{
    id <SSIPacketList> list = packet;

    // 갯수 출력
    [_lblCertificateCount setText:[@([list count]) description]];

    // 총액 계산
    NSUInteger totalBalance = 0;
    for (id <SSIPacketPossess> possess in list)
        totalBalance += [possess balance];
    
    // 총액 출력
    [_lblCertificateTotalBalance setText:[@(totalBalance) description]];
    
    [self setNeedsDisplay];
}

packet은 SSIPacketList라는 기능이 부여된 개체 입니다. count와 List<SSIPacketPossess>를 반환하는 기능이 부여되어 있습니다.
List에서도 SSIPacketPossess 인터페이스로 반환합니다. SSIPacketPossess는 총액을 반환하는 기능이 부여 되어 있습니다.



이와 같이 프로토콜(인터페이스)를 델리게이트로 생각하는 것도 틀린 바는 아니나 객체지향에서의 인터페이스는 좀더 근본적으로 시사하는게 다릅니다. 많은 공부와 연구를 통해 근본적으로 시사하는 것을 탐구하고 적용해 보길 바라겠습니다.

'개발지식창고 > iOS' 카테고리의 다른 글

IBOutlet과 IB(Interface Builder)  (0) 2013.12.19
Apple iOS Deverloper Library Site  (0) 2013.12.19
String과 Int 변환  (0) 2013.12.19
Entry point ~ View 전까지의 Process  (0) 2013.08.20
Object C 정리  (0) 2013.08.19
Posted by 모과이IT
,

1. Main 함수 기본 구조


int main(int argc, char *argv[])

{

NSAutoreleasePool * pool = [[NSAutoreleasePool allocinit];

int retVal = UIApplicationMain(argc, argv, nil@"MyAppDelegate");

[pool release];

return retVal;

}


=> 오토릴리즈풀 객체를 생성한 후, UIApplicationMain 함수를 호출하여 Application 객체를 만들고, 그 객체의 델리게이트를 지정하여 이벤트루프를 시작한다. ( 프로그램마다 Application 객체를 하나씩 가지게 되는데, 그 객체의 델리게이트도 하나씩 지정을 한다. )

이벤트루프가 완료되면 오토릴리즈풀 객체를 해제하고 프로그램이 종료된다.



2. 델리게이트클래스에서 Application 객체로 전달되는 메시지 처리


@interface MyAppDelegate : NSObject <UIApplicationDelegate> 

@end


@implementation MyAppDelegate


// On launch, create a basic window

- (void)applicationDidFinishLaunching:(UIApplication *)application {

UIWindow *window = [[UIWindow allocinitWithFrame:[[UIScreenmainScreenbounds]];

MyViewController *ctl = [[MyViewController alloc] init];

[window addSubview:ctl.view];

[window makeKeyAndVisible];

}


- (void)applicationWillTerminate:(UIApplication *)application  {

// handle any final state matters here

}


- (void)dealloc {

[super dealloc];

}


@end


=> Application 객체의 대리자가 되려면 UIApplicationDelegate 프로토콜을 구현하고 있어야 한다. MyAppDelegate는 UIApplicationDelegate 프로토콜을 따른다.

애플리케이션이 실행될 준비가 완료되면 Application 객체에게 applicationDidFinishLaunching 메시지가 날라가는데, 대리자가 MyAppDelegate 으로 지정되어 있으므로, MyAppDelegate에서 구현된 applicationDidFinishLaunching 이 호출되게 된다.


아이폰 어플리케이션은 창이 하나 있고 그 창안에 뷰들이 여러개 존재하는 형태가 된다.

그래서, 첫번째로 창에 해당하는 UIWindow 객체를 생성한다.

그다음, 필요한 뷰컨트롤러 객체(MyViewController)를 생성하여 addSubview 메시지로 자식으로 추가를 하게 된다.

그리고, makeKeyAndVisible 메시지를 통해서 해당 윈도우를 활성화 시킨다.



3. MyViewController 의 loadView 메시지 처리


UIViewController로 부터 상속을 받는 MyViewController에서는 loadView 를 오버라이드를 해준다.

이 메시지에서 뷰를 꾸미게 된다.



출처 : http://devroid.com/80098624144


'개발지식창고 > iOS' 카테고리의 다른 글

IBOutlet과 IB(Interface Builder)  (0) 2013.12.19
Apple iOS Deverloper Library Site  (0) 2013.12.19
String과 Int 변환  (0) 2013.12.19
프로토콜  (0) 2013.09.03
Object C 정리  (0) 2013.08.19
Posted by 모과이IT
,

http://adolys.tistory.com/entry/%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-%EB%A9%94%EC%86%8C%EB%93%9CInstance-Method%EC%99%80-%ED%81%B4%EB%9E%98%EC%8A%A4-%EB%A9%94%EC%86%8C%EB%93%9CClass-Method

'개발지식창고 > C++' 카테고리의 다른 글

DLL 제작 기법  (0) 2017.06.30
COM+ 서버  (0) 2015.02.09
#pragma pack(push, 1)  (0) 2011.11.28
형변환 (Typecasting) - const_cast, reinterpret_cast, static_cast, dynamic_cast  (0) 2010.11.14
예외(Exception) 처리 try, catch, throw  (0) 2010.11.14
Posted by 모과이IT
,

코딩 기본 규칙 

1. 클래스는 대문자로 시작한다.

2. 인스턴스 변수는  소문자로 시작한다.

  * private 일 경우 _xxx, __xxx 허용

 

 

* 최상위 클래스

NSObject (자바의 Object같은 것인듯)

클래스를 만들때 NSObject를 상속받는다.

 

* 상속, 클래스 변수, 연산자 오버로딩

다중 상속을 지원하지 않는다.

클래스 변수를 지원하지 않는다. (자바와는 다른듯?)

연산자 오버로딩을 지원하지 않는다.

아규먼트 오버로딩을 지원하지 않는다.

 

* id, self, super, nil, @""

id : 객체를 가리키는 포인터 void*와 같다.

self : 자신을 가리키는 포인터. (자바의 this)

super : 자바의 super

nil : 객체가 없음.

NULL : C와 같음

c style 의 스트링 "하하"

유니코드 스트링 @"하하"

 

* 메소드의 기본 리턴타입은 id

 - (id)sayHello

 - sayHello

두가지는 같은 의미. 즉 명시하지 않으면 기본으로 객체 타입을 리턴한다.

 

* 객체 생성

MyObject *className = [[MyObject alloc] init];

alloc은 클래스 메소드. init은 인스턴스 메소드

alloc - 메모리 준비, init - 인스턴스 변수 초기화

 

* 메세지 보내기(자바의 "함수 호출" 이란 뜻인듯)

Object C 는 [ 구문 ]; 형식을 취한다.

[myObject draw];

 

* 메세지 인자

메세지 인자는 : 로 구분한다.

[myObject drawWithX:pointX withY:point Y];

[myObject drawWithX:pointX:point Y];

 

두가지는 같은 뜻이지만 위에것이 더 명확하다.

 

 

* import

C의 include도 허용하지만 자바처럼 import를 사용하는 듯하다.

 

* 클래스 선언

클래스이름.h 로 파일 생성

Foundation이나 UIKit을 import

-> #import <Foundation/Foundation.h>

-> #import <UIKit/UIKit.h>

 

@interface 클래스이름 : 상위클래스 로 선언

+(Return type) ClassMethod; -> Class Method Declare

-(Return type) InstanceMethod; -> Instance Method

@end 로 닫는다.

 

클래스 선언 예제

#import <Foundation/Foundation.h>

 

@interface MyName:NSObject

{

NSString *name;

}

+(MyName*) newInstance; //or +(Id)newInstance;

-(Id)initWithName:(NSString *)name;

@end

 

* 클래스 구현

클래스이름.m 으로 파일 생성

#import "클래스이름.h" 로 미리 선언한 헤더 import

@implementation MyName 으로 구현시작

+(Return type)ClassMethod {...}; 구현

-(Return type)InstanceMethod {...}; 구현

 

클래스 구현 예제

#import "MyName.h"

 

@implementation MyName

+(MyName*)newInstance

{

// 내용 구현

return [[MyName alloc] initWithName:null] autorelease];

}

-(Id)initWithName:(NSString*)name

{

// 내용 구현

if(self = [super init])

{

 

}

return self;

}

@end






출처 : http://blog.naver.com/PostView.nhn?blogId=marlboroyw&logNo=130126597618


'개발지식창고 > iOS' 카테고리의 다른 글

IBOutlet과 IB(Interface Builder)  (0) 2013.12.19
Apple iOS Deverloper Library Site  (0) 2013.12.19
String과 Int 변환  (0) 2013.12.19
프로토콜  (0) 2013.09.03
Entry point ~ View 전까지의 Process  (0) 2013.08.20
Posted by 모과이IT
,

http://stbaeya.com/tc/361?category=45

Posted by 모과이IT
,
아시다시피 안드로이드에서의 리소스 관리는 R.java 파일에서 이루어지고 있다.

개발자가 매번 추가하지 않아도, int 정수자료형으로 재생성 되고 있다.

그렇타면...
xml내의 수많은 view들의 리소스 아이디를 찾기 위해서

for문 내에

for( int i =0; i<99; i++){
findViewById(R.id.+"textview"+i);
}

이런식으로 선언하면 로직은 에러가 안나지만... 리소스를 찾지를 못한다.

그래서 안드로이드 리소스 함수중에 getIdentifier를 이용하면 비슷한 형태로 적용할 수 있다.

getIdentifier()함수 내에 인자로 아래 3개의
리소스 아이디(문자열), id/drawable 정의타입, 패키지명 을 넘기면 된다.

for(int i = 0; i< 99; i++){

 int resId = getResources().getIdentifier("textview"+i, "id", "com..");
...
}

버튼에 이벤트를 적용하려고 할때 리스너를 거는 방법 또한 동일하게 적용하면 된다.

 

출처 :  http://stbaeya.com/tc/352

 

Posted by 모과이IT
,

 

http://www.sqlite.org/datatype3.html

http://www.tutorialspoint.com/sqlite/index.htm

 

 

'개발지식창고 > DataBase' 카테고리의 다른 글

Mysql에서 InnoDB 활성화시키기  (0) 2015.09.07
mysql 외부 접속 허용하기  (0) 2015.06.14
[SQLITE] 자료형  (0) 2013.06.28
MFC 환경에서 MySQL 연동하는 방법  (0) 2010.08.31
MySQL : Data Type (1 of 2)  (0) 2010.08.31
Posted by 모과이IT
,

출처 : http://blog.daum.net/sukee/17162407

저장형과 컬럼 친화성

SQLite에는 저장형(Storage Class)와 컬럼 친화성(Column Affinity)이 있습니다.

저장형은 각 값에 붙여지는 태그이며, 정렬이나 비교와 같은 연산을 실행할 때 사용됩니다. 컬럼 친화성은 다른 데이터베이스와 호환을 위해 제공됩니다. 이미 오라클이나 MySQL과 같은 데이터베이스에 경험이 있는 분들에게는 이 부분이 많이 헷갈릴 수 있습니다. 


저장형

저장형(Storage Class)은 각 값에 붙는 타입입니다. 다시 한 번 강조하자면, 각 값에 붙는 타입입니다. 오라클이나 MySQL 같은 경우에는 타입이 각 컬럼에 부여됩니다. 예를 들어, MySQL에서 테이블을 만들 때, 어떤 컬럼의 타입을 정수로 결정하면, 이후로 그 테이블의 그 컬럼에는 정수만이 들어갈 수 있습니다. 다시 말해, 정수가 아니면 안 되는 거죠. SQLite는 이와 같지 않습니다.

다음은 SQLite의 다섯 저장형입니다:

NULL:    값이 NULL인 경우.

INTEGER: 부호 있는 정수. 상황에 따라 1, 2, 3, 4, 6, 8 바이트가 됨.

REAL:    부동소수점. IEEE 부동소수 규격에 따른 8바이트.

TEXT:    문자(열). 기본적으로 UTF-8으로 저장되며 UTF-16 BE나 UTF-16 LE를 사용할 수 있음.

BLOB:    이진 데이터. 외부에서 전달된 데이터를 그대로 저장됨.

위 저장형은 다음 절에서 설명하는 컬럼 친화성과 함께 봐야 이해가 되므로, 저장형은 SQLite에서 타입을 의미한다는 정도만 알고 일단 패스!

컬럼 친화성

먼저, 우리에게 익숙한 다음 쿼리로 시작해 보겠습니다.

sqlite> CREATE TABLE tbl_test (One INTEGER, Two INTEGER);

위 쿼리로 두 개의 컬럼(One, Two)이 있는 테이블(tbl_test)을 하나 만들었습니다. 두 컬럼 모두 정수형이기 때문에, 위 테이블에는 정수만이 들어갈 수 있습니다. 그렇죠? 그러나 SQLite는 다릅니다! 다음으로 직접 확인해 보죠.

sqlite> INSERT INTO tbl_test VALUES (123, 456);
sqlite> INSERT INTO tbl_test VALUES (123, 456.7);
sqlite> INSERT INTO tbl_test VALUES (123, 456.0);
sqlite> INSERT INTO tbl_test VALUES (123, '456');
sqlite> INSERT INTO tbl_test VALUES (123, '456two');
sqlite> INSERT INTO tbl_test VALUES (123, 'ant');
sqlite> INSERT INTO tbl_test VALUES (123, ant);

위 실행중에서 가장 마지막 것만 오류가 발생하고 나머지는 실행됩니다. 즉 값이 테이블에 저장됩니다. 다음처럼 직접 확인해 보세요.

sqlite> SELECT * FROM tbl_test;

위에서 테이블을 만들 때, INTEGER란 키워드를 사용했는데 이는 컬럼 친화성을 지정하는 키워드 중에 하나였습니다. SQLite에는 모두 다섯 개의 컬럼 친화성이 있습니다: TEXT, NUMERIC, INTEGER, REAL, NONE.

자~ 여기서 맥(?)을 함 짚고 넘어 가겠습니다: 테이블을 생성하는 쿼리문이 동일하기 때문에, 여러분은 위의 INTEGER가 컬럼 타입이라고 생각하게 된 겁니다. SQLite에서는 컬럼 타입(Column Type)이 아니라 컬럼 친화성(Column Affinity)으로 사용되고 있습니다. 컬럼 타입은 딱 하나를 결정하는 것이고, 컬럼 친화성은 어떤 우선 순위를 취할지 결정하는 겁니다. 어떤 우선 순위라?

우리는 테이블을 만들고 거기에 데이터를 저장합니다; 레코드를 기본 단위로 저장합니다. 위 테이블 예에서, 오라클이나 MySQL은 레코드를 저장할 때마다 컬럼의 값들이 항상 정수입니다. 레코드가 추가되더라도 이건 변하지 않고 고정된 거죠. SQLite에서는 동일한 컬럼일지라도 각 레코드마다 다른 타입을 가질 수 있습니다.

아래 쿼리는 위에서 사용했던 것과 동일한데, 각 쿼리의 끝에 저장형을 보여주고 있습니다.(컬럼 친화성이랑 헷갈리지 마세요)

sqlite> INSERT INTO tbl_test VALUES (123, 456);       --(INTEGER, INTEGER)
sqlite> INSERT INTO tbl_test VALUES (123, 456.7);     --(INTEGER, REAL)
sqlite> INSERT INTO tbl_test VALUES (123, 456.0);     --(INTEGER, INTEGER)
sqlite> INSERT INTO tbl_test VALUES (123, '456');     --(INTEGER, INTEGER)
sqlite> INSERT INTO tbl_test VALUES (123, '456two');  --(INTEGER, TEXT) 
sqlite> INSERT INTO tbl_test VALUES (123, 'ant');     --(INTEGER, TEXT) 
sqlite> INSERT INTO tbl_test VALUES (123, ant);       --ERROR

위 쿼리에서 눈여겨 볼 부분은 두 번째 컬럼(컬럼 Two, 컬럼 친화성 INTEGER)입니다. 먼저 첫 번째 쿼리에서, 정수 값(456)이 입력되었으므로 저장형은 INTEGER가 됩니다.(INTEGER란 키워드는 컬럼 친화성과 저장형에 모두 있으므로 헷갈리지 마세요) 두 번째 쿼리에서는 정수가 아닙니다(456.7). SQLite는, 컬럼 친화성이 INTEGER이므로, 먼저 이 값이 정수가 될 수 있는지 확인합니다. 그런데 정수가 될 수가 없기 때문에 차선으로 REAL 저장형을 선택한 것입니다. 세 번째 쿼리에서도 정수로 변환 가능한지 확인하는데, 이번에는 가능합니다. 때문에 INTEGER 저장형을 부여합니다. 네 번째도 세번째에서와 마찬가지로 정수로 변환 가능하므로 INTEGER 저장형을 부여했습니다. 그 다음 값('456two')은 어떻습니까? 이 값은 정수가 될 수도 없고 부동 소수가 될 수도 없습니다. 그 다음으로 TEXT로 변환 가능하기 때문에 TEXT 저장형을 부여했습니다. 그 다음 여섯 번째도 마찬가지입니다. 마지막 쿼리에서의 값(ant)은 정수도 부동 소수도 될 수가 없기 때문에 텍스트가 되야 하는데, 작은 따옴표가 없기 때문에 에러를 발생합니다. 컬럼 친화성에 상관없이 작은 따옴표를 사용하지 않는 값의 경우에는 숫자만이 가능합니다.

음, 여기서 말한 컬럼 친화성이란 입력되는 값에 따라 어떤 타입을 우선해서 선택할까를 의미합니다. 그럼 다음 번에는 다섯 개 컬럼 친화성의 우선 순위에 대해서 알아 보도록 하겠습니다.

자동 증가 Autoincrement

자동 증가는 보통 테이블의 키로 사용됩니다. 그래서 유일한 값을 갖는게 중요하지요. 다른 테이블에서 외래키(foreign key)로 사용될 때도 필요하구요. 다음 처럼 간단합니다.

CREATE TABLE tbl_test (
  RowID INTEGER PRIMARY KEY AUTOINCREMENT,
  Name  TEXT,
  Age   INTEGER
);

**참고  http://qkrgns208.tistory.com/119?srchid=BR1http://qkrgns208.tistory.com/119


 

'개발지식창고 > DataBase' 카테고리의 다른 글

mysql 외부 접속 허용하기  (0) 2015.06.14
[SQLITE] SQLITE 관련 사이트  (0) 2013.06.28
MFC 환경에서 MySQL 연동하는 방법  (0) 2010.08.31
MySQL : Data Type (1 of 2)  (0) 2010.08.31
MFC MYSQL 연동  (0) 2010.08.31
Posted by 모과이IT
,