Search results for '전체'

  1. 2019.02.20 -- [FMX][팁] 파이어몽키 버튼의 배경색상 변경하기
  2. 2019.02.20 -- [FMX][팁] 파이어몽키 TComboBox 글자 크기 변경
  3. 2019.02.20 -- [개발환경설정] 윈도우즈 환경에 Git 설치하기
  4. 2019.01.30 -- 델파이 코드 작성 규칙
  5. 2019.01.23 -- 이더넷 어댑터 정보((MacAddress, IP 등) 목록 알아오기
  6. 2019.01.14 -- CEF4Delphi(크로미움 기반 웹브라우저) 컴포넌트 설치 및 실행하기 (3)
  7. 2019.01.14 -- [REST API] MAC(Message Authentication Code)/HMAC 델파이로 구현하기
  8. 2018.12.20 -- OAuth 2.0 연동 - 카카오 API(카카오톡 프로필)
  9. 2017.12.19 -- RFID 리더(한미IT RF Prisma) 연동하기 - 델파이에서 JAR 이용 (2)
  10. 2017.12.06 -- WaitDialog 구현 - 재사용 가능한 프레임 구현하기
  11. 2017.11.22 -- [튜토리얼] 메일 전송(IdSMTP 이용) (2)
  12. 2017.11.22 -- [튜토리얼] FTP 업로드(TIdFTP 이용)
  13. 2017.11.02 -- 델파이/C++빌더에 TTcpClient, TTcpServer, TUdpSocket 등록하기
  14. 2017.10.30 -- 안면인식(Face Detection) 라이브러리(안드로이드, iOS)
  15. 2017.10.30 -- TTS(Text-to-Speech) 라이브러리(윈도우, 맥OS, iOS, 안드로이드)
  16. 2017.10.30 -- 델파이로 빅데이터 데이터베이스 연동하기(Cassandra, Couchbase, MongoDB)
  17. 2017.09.20 -- [FMX] TListView 더보기 버튼 구현하기
  18. 2017.09.18 -- [REST API] 다음 Kakao > 로컬 > 주소검색 연동하기
  19. 2017.09.12 -- [FMX] 폼의 높이를 애니메이션으로 변경하기, 툴바를 끌어 폼 이동하기
  20. 2017.09.08 -- [FMX] iOS 시스템 볼륨 제어하기

[FMX][팁] 파이어몽키 버튼의 배경색상 변경하기

2019.02.20 16:37

파이어몽키 버튼(TButton)에 배경색을 입히는 작업을 안내합니다.


버튼은 배경색 관련 속성을 제공하지 않아 스타일을 변경 해 적용해야 합니다.


커스텀 스타일 변경

버튼에 우측마우스 클릭 후 [Edit Custom Style...] 메뉴를 선택 해 Style Designer 화면으로 이동합니다.


관련 스타일 검토

Structure 패널에서 추가된 스타일(Button2Style1) 선택 후 배경색 관련된 항목이 있는지 확인합니다.

background 항목의 경우 TButtonStyleObject로 배경을 이미지에서 지정하는 방식으로 직접 배경색을 지정할 수 없습니다.


배경을 지정할 컴포넌트 추가 및 설정

배경을 지정할 컴포넌트를 직접 추가합니다.

background 항목의 자식으로 Rectangle 컴포넌트를 추가합니다.


추가된 Rectangle 컴포넌트 선택 후 속성을 편집합니다.

  • Align = Client
  • Fill.Color = 원하는 색상
  • Opacity = 원하는 투명도
  • HitTest = False(클릭이 되지 않도록)
추가된 스타일(Button2Style1 등)의 StyleName 속성도 알아보기 좋게 변경합니다.(예> BlueButton, RedButton)

Style Designer의 툴바 가장 오른쪽의 Apply style 버튼을 클릭해 적용합니다.

버튼 스타일 적용
다시 폼 디자이너로 돌아와 버튼의 스타일을 지정합니다.



버튼 선택 후 StyleLookup 속성을 보면 앞에서 추가한 스타일을 선택할 수 있습니다. 스타일은 여러개의 버튼에 동일하게 적용할 수 있습니다.



험프리.김현수 파이어몽키

[FMX][팁] 파이어몽키 TComboBox 글자 크기 변경

2019.02.20 16:18

파이어몽키의 TComboBox는 TextSetting과 같은 속성을 제공하지 않아 폰트 설정이 제한됩니다.


코드를 통해 콤보박스(TComboBox)의 폰트를 설정하는 방법을 안내합니다.

다음 코드는 콤보박스의 글자크기를 20으로 변경한 예제입니다.

procedure StyleComboBoxItems(ComboBox:TComboBox; Size:Single);
var
  Item : TListBoxItem;
  i : Integer;
begin

  for i := 0 to ComboBox.Count-1 do begin
    Item := ComboBox.ListItems[i];
//    Item.Font.Family := Family; //'Arial';
    Item.Font.Size := Size; //20;
    // Item.FontColor := TAlphaColorRec.Red;
    Item.StyledSettings := Item.StyledSettings - [TStyledSetting.Size];
    // Item.Text := '*'+Item.Text;
  end;
end;

procedure TForm3.FormCreate(Sender: TObject);
begin
  ComboBox1.Items.Add('추가 항목');
  ComboBox1.Items.Add('추가 항목');
  ComboBox1.Items.Add('추가 항목');

  StyleComboBoxItems(ComboBox1, 20);
end;


결과는 아래와 같으며, 폰트의 글꼴 및 색상 변경은 위 코드를 참고해 기능 추가하시기 바랍니다.


참고



험프리.김현수 파이어몽키

[개발환경설정] 윈도우즈 환경에 Git 설치하기

2019.02.20 13:50

Git 설치

다운로드

다음 링크에서 윈도우즈 인스톨러를 다운로드합니다.


git.exe 파일을 실행해 설치를 시작합니다.


라이선스 확인

라이선스 확인 후 [Next] 버튼을 클릭합니다.

설치할 컴포넌트 선택

중요한 항목은 이미 선택되어 있으니 [Next] 버튼 클릭합니다.


기본 편집기 선택

git에서 사용할 기본 편집기 선택, 가장 편한 에디터 선택 후 [Next] 버튼 클릭


PATH 환경설정

Git 명령을 실행할 환경을 선택 아래 설명을 참고해 선택 후 [Next] 버튼 클릭

(윈도우즈 명령 프롬프트에서도 Git 명령어 실행이 필요한 경우 2번째 옵션 선택)


Use Git from Git Bash only: Git Bash(Git에서 제공하는 명령어 입력 및 실행 프로그램)에서만 Git 명령어 수행

Git from the command line and also from 3rd-party software: 명령어(Git Bash와 명령 프롬프트커맨드라인)와 써드파티 소프트웨어에서 git을 사용할 수 있도록 (안전한)경로 추가

Use Git and optional Unix tools from the Windows Command Prompt: 윈도우 명령 프롬프트에서 Git과 유닉스 도구를 모두 사용

경고: 이것은 윈도우의 "find"와 "sort"와 같은 도구보다 우선함. 이 옵션은 영향을 알고 있는 경우에 한해 사용 할 것


SSH 프로그램 선택

Use OpenSSH(Git과 함께 제공하는 ssh.exe 사용) 선택 후 [Next] 버튼 클릭


HTTPS 연결 라이브러리 선택

Use the OpenSSL Libray(OpenSSL 라이브러리를 통해 인증서 검증) 선택 후 [Next] 버튼 클릭


Line ending 스타일 선택

첫번째 항목 선택 후 [Next] 버튼 클릭


Checkout Windows-style, commit Unix-style line endings: Checkout 시 윈도우 스타일, Commit 시 유닉스 스타일로 적용 

Checkout as-is, commit Unix-style line endings: Checkout 시 그대로, Commit 시 유닉스 스타일로 적용 

Checkout as-is, commit as-is: Checkout, Commit 둘다 그대로 사용, 크로스 플랫폼 프로젝트에서 이 옵션 사용하지 않는 것이 좋음


Git Bash의 터미널 에뮬레이터 선택

Use MinTTY 선택 후 [Next] 버튼 클릭


기타 옵션 선택

필요 옵션 선택 후 [Install] 버튼 클릭 해 설치



Enable file system caching: 파일 시스템 데이터를 메모리 캐쉬해 성능 향상

Enable Git Credential Manager: Github 등에 대한 다중 인증 지원을 위해 Git Credential Manager 활성화

Enable symbolic links: 심볼릭 링크 활성화


설치 완료


험프리.김현수 Team Thoth/오픈소스

델파이 코드 작성 규칙

2019.01.30 13:37

데브기어에서 진행 중인 프로젝트 과정에서 사용 중인 코드작성 규칙을 공유합니다.

https://docs.google.com/document/d/1eYWWv_YJRl-FYw3FkcIaBRSzaHsL0V-zRjA2rzJsPZM



험프리.김현수 Delphi/C++Builder

이더넷 어댑터 정보((MacAddress, IP 등) 목록 알아오기

2019.01.23 16:08

윈도우에 설치된 네트워크(이더넷 어댑터) 정보를 알아오는 방법입니다.(10.3 리오에서 구현했습니다.)


uses 절에 Winapi.IPTypes, Winapi.IPHlpAPi 추가해야 합니다.

var
  I: integer;
  NumInterfaces: DWORD;
  AdapterInfo: array of TIpAdapterInfo;  // uses Winapi.IpTypes
  OutBufLen: ULONG;
begin
  GetNumberOfInterfaces(NumInterfaces); // uses Winapi.IpHlpApi
  SetLength(AdapterInfo, NumInterfaces);
  OutBufLen := NumInterfaces * SizeOf(TIpAdapterInfo);
  GetAdaptersInfo(@AdapterInfo[0], OutBufLen);

  Memo1.Lines.Clear;
  for I := 0 to NumInterfaces - 1 do begin
    if AdapterInfo[I].Description = '' then
      Continue;
    Memo1.Lines.Add(AdapterInfo[I].Description);
    Memo1.Lines.Add(AdapterInfo[I].IpAddressList.IpAddress.S);
    Memo1.Lines.Add(Format('%.2x:%.2x:%.2x:%.2x:%.2x:%.2x',
      [AdapterInfo[I].Address[0], AdapterInfo[I].Address[1],
       AdapterInfo[I].Address[2], AdapterInfo[I].Address[3],
       AdapterInfo[I].Address[4], AdapterInfo[I].Address[5]]));
  end;

기타 정보도 TIpAdapterInfo 구조체를 통해 알아올 수 있습니다.


메모에 출력된 결과 화면


참고


험프리.김현수 Delphi/C++Builder

CEF4Delphi(크로미움 기반 웹브라우저) 컴포넌트 설치 및 실행하기

2019.01.14 17:06

REST API 관련 컨설팅 중 학습한 내용을 공유합니다.


고객사의 요청으로 VendHQ 사의 REST 서비스와 연동을 진행했습니다.

OAuth 2.0 연동 중 웹브라우저 이슈가 있어 해결방안을 공유합니다.


OAuth 2.0 인증 시 크게 3가지 단계로 진행합니다.
1) 서비스의 인증페이지에 로그인 해 인증코드를 받는다.
2) 인증코드를 이용해 엑세스 토큰을 취득한다.
3) 엑세스 토큰을 이용해 서비스에 접근한다.

이슈는 1)번 과정에서 발생했습니다.
델파이 내장 웹브라우저 컴포넌트(TWebBrowser)가 vend사의 로그인 페이지를 정상 출력하지 않아 다음 단계로 진행되지 않습니다.(vend사에서 표준을 지키지 않고 페이지를 만든것으로 예상됩니다.)

다음과 같이 스타일이 적용되지 않고, 허용 버튼(Allow Access) 클릭이 되지 않습니다.

해당 이슈는 VCL과 FMX 두가지 TWebBrowser가 동일합니다.


그래서 다른 대안으로 크롬미움 기반 웹브라우저 써드파티 컴포넌트(크로미움)를 테스트 해봤습니다.
해당 컴포넌트로는 인증 페이지가 정상 출력되고, 인증코드를 받아오는 부분까지 정상 진행되었습니다.


크로미움 기반 웹브라우저 컴포넌트 설치

CEF4Delphi는 크로미움 기반 웹브라우저 써드파티 컴포넌트로 오픈소스로 진행됩니다.

깃허브 저장소를 통해 제공하고 있습니다.

CEF4Delphi를 사용하려면 컴포넌트 설치 후 실행(및 배포) 시 크로미움 관련 라이브러리들을 함께 배포해야 합니다.


CEF4Delphi 다운로드


CEF4Delphi 깃허브 페이지에서 컴포넌트를 다운로드 합니다.(Clone or download > Download ZIP)


다운로드 받은 파일을 압축 해제 후 적절한 라이브러리 저장 경로에 이동합니다.(해당 경로의 패키지를 설치하고 델파이에 링크하게 됩니다.)


CEF4Delphi 컴포넌트 설치

델파이를 실행하고 다운로드 받은 파일들에서 .\packages\CEF4Delphi.dpk 패키지 프로젝트 파일을 엽니다.

프로젝트에서 오른쪽 마우스 클릭 후 팝업 메뉴에서 인스톨 메뉴를 선택해 설치합니다.

 


라이브러리 패스 추가

패키지 설치 후 CEF4Delpih 소스코드를 델파이 라이브러리 패스에 추가합니다.


델파이 라이브러리 화면을 표시합니다.

Tools > Options, Language > Delphi Options > Library


플랫폼을 선택 후 Library path에 CEF4Delphi 소스 디렉토리를 추가합니다.


CEF4Delphi 프로그램 실행

패키지(컴포넌트)를 정상 설치 후 데모를 실행하면 오류가 발생합니다.

내장 된 데모 중 SimpleBrowser2(.\CEF4Delphi\demos\SimpleBrowser2)를 열고 실행 시 다음과 같은 오류가 발생합니다.


오류 내용을 보면 CEF3 바이너리가 누락되었다는 내용입니다.

일반적으로 위와 같은 오류의 조치방법은 실행파일과 같은 경로 또는 시스템 패스에 해당 라이브러리들을 복사하는 방법이 있습니다.

하지만 CEF4Delphi는 소스코드 내에서 해당 경로를 지정하는 방법을 제공합니다.


CEF 바이너리 지정

SimpleBrowser2의 프로젝트 파일을 열면 다음과 같이 GlobalCEFApp 전역변수와 각종 경로를 지정하는 코드가 주석처리 되어 있습니다.

경로를 지정하는 코드의 주석을 풀고, 해당 경로에 CEF 바이너리를 넣거나 경로를 임의로 지정할 수 있습니다.


GlobalCEFApp.FrameworkDirPath := 'cef'; 경로는 실행파일과 같은 경로의 cef 디렉토리를 의미합니다.


우리는 위의 코드에서 주석 해제 후 지정한 디렉토리(.\cef)에 CEF 바이너리를 복사하도록 하겠습니다.

CEF 바이너리 다운로드

CEF4Delphi 깃허브 페이지에서 CEF 바이너리를 다운로드 제공합니다.

윈도우즈 32비트 플랫폼 애플리케이션에서 CEF 이용 시 32 bits를 다운로드 합니다.
(64비트 프로젝트 개발 시 64 bits를 다운로드 합니다.)


CEF4Delphi 컴포넌트의 경로 하위 bin 디렉토리에 다운로드 받은 파일을 압축해제 합니다.

CEF 바이너리 복사

SimpleBrowser2 데모를 컴파일하면 .\CEF4Delphi\bin 디렉토리에 실행파일이 생성됩니다.
(Project > Options > Delphi Compiler > Output directory가 "..\..\bin"으로 설정)


bin 디렉토리 하위에 cef 디렉토리를 생성합니다.


CEF 바이너리 파일 중 아래 디렉토리의 모든 파일과 디렉토리를 생성한 cef 디렉토리에 복사합니다.

  • Release\*.*
  • Resources\*.*

이후 다시 데모 프로젝트를 실행하면 오류없이 정상 실행을 확인할 수 있습니다.


배포 시에도 실행파일 하위 cef 디렉토리를 함께 배포하거나, CEF 바이너리 디렉토리를 지정해야 합니다.


관련/참고 링크



험프리.김현수 데이터 엑세스

  1. Blog Icon
    bioman

    좋은 자료 공유 감사합니다.

  2. Blog Icon

    비밀댓글입니다

  3. 다음 링크의 파일을 다운로드 받아 압축해재 후 사용하시기 바랍니다.(7zip 등의 압축프로그램을 이용해 압축해제 해보세요.)
    32bit
    http://opensource.spotify.com/cefbuilds/cef_binary_3.3626.1886.g162fdec_windows32.tar.bz2
    64bit
    http://opensource.spotify.com/cefbuilds/cef_binary_3.3626.1886.g162fdec_windows64.tar.bz2

[REST API] MAC(Message Authentication Code)/HMAC 델파이로 구현하기

2019.01.14 11:56

REST API 관련 컨설팅 중 학습한 내용을 공유합니다.


한 고객사의 요청으로 Unleashed 사의 REST 서비스와 연동을 진행했습니다.

그 과정 중 HMAC(해시 기반 메시지 인증 코드) 구현 과정을 공유합니다.


HMAC은 Unleashed 사 뿐아니라 AWS의 REST API 연동에도 사용되는 등 많은 REST 서비스에 구현되는 내용입니다.


MAC과 HMAC

먼저 MAC(Message Authenticate Code: 메시지 인증 코드)를 살펴봅니다.

(출처: https://ko.wikipedia.org/wiki/메시지_인증_코드)


MAC는 발신자(Sender)와 수신자(Receiver) 사이에 메시지 변조 여부를 확인하기 위한 메시지 인증 방식입니다.

위 그림을 통해 설명하면, 

Sender는 보내는 메시지(MESSAGE)와 지정된 키(Key)를 조합해 MAC을 만들고 메시지와 MAC을 전달합니다.

Receiver는 메시지와 MAC를 수신 후 메시지와 지정된 키를 조합해 MAC을 만들어 수신한 MAC과 비교해 데이터의 위변조를 판단할 수 있습니다.


HMAC(Hashed MAC)는 MAC Algorithm에 해쉬 함수를 적용해 암호화 하는 방식입니다.


HMAC 예시

제가 진행한 Unleashed 사는 API 요청 시 HTTP 해더에 다음 정보를 포함해야 합니다.

  • Content-Type, Accept
  • api-auth-id
  • api-auth-signature
Content-type과 Accept는 송수신 시의 데이터 포맷인 application/json을 입력하면 됩니다.
api-auth-id는 서비스 등록 시 발급받은 API ID를 입력하면 됩니다.
api-auth-signature는 HMAC을 생성해 입력해야 합니다.

서비스 제공사의 문서를 보면 HMAC-SHA256을 어떻게 만들어야 하는지 안내합니다.

위 문서 중 일부는 다음과 같습니다.

The method signature must be generated by taking the query string, and creating a HMAC-SHA256 signature using your API key as the secret key.
(메소드 시그니처는 쿼리 스트링을 가져와 API Key를 시크릿 키로 HMAC-SHA256 시그니처를 생성해야 한다.)

위에서 API 키는 서비스 등록시 발급받은 값입니다.


쿼리 스트링은 URL 중 "?" 뒤의 문자열입니다. 예를 들면

Customers?customerCode=ACME 중 customerCode=ACME가 쿼리 스트링입니다.


HMAC-SHA256은 다음과 같이 구현할 수 있습니다.

HMAC-SHA256

다음 샘플은 쿼리스트링(ProductCode=XXX)와 API Key(UNLEASHED_API_KEY: 상수)를 이용해 HMAC을 SHA256으로 시그니처를 생성해 HTTP 해더에 추가하는 내용입니다.

uses
  System.Hash,          // sha256
  System.NetEncoding;   // base64

var
  signature: string;
  param: string;
begin
  param := 'ProductCode=' + AProductCode;

  // PHP: base64_encode(hash_hmac('sha256', $request, $key, true));
  signature := TBase64Encoding.Base64.EncodeBytesToString(
                  THashSHA2.GetHMACAsBytes(param, UNLEASHED_API_KEY, SHA256));

  RESTRequest1.Params.AddItem('api-auth-id', UNLEASHED_API_ID, pkHTTPHEADER);
  RESTRequest1.Params.AddItem('api-auth-signature', signature, pkHTTPHEADER, [poDoNotEncode]);
end;


추가 학습할 내용

HMAC 인증외에 OAuth 2.0 인증도 많이 사용됩니다.

다음 글을 통해 OAuth 2.0을 통해 카카오 API에 연동하는 내용을 살펴볼 수 있습니다.

다음 글들을 통해 REST API를 이해하고 실습할 수 있습니다.

험프리.김현수 데이터 엑세스

OAuth 2.0 연동 - 카카오 API(카카오톡 프로필)

2018.12.20 01:35


이 글에서는 OAuth 2.0을 이용해 카카오 API와 연동하는 방법을 델파이를 통해 알아봅니다.

이 글을 통해 카카오톡 프로필 정보와 사진을 델파이 애플리케이션에서 불러오는 예제를 작성할 수 있습니다.


OAuth 2.0

API(또는 서비스) 이용 시 인증(Authentication)과 리소스(제공 서비스)에 대한 권한부여(Authorization)는 필수사항입니다. 인증과 권한부여의 대표적인 방법 중 하나가 OAuth입니다.


OAuth는 서버와 클라이언트 사이에 인증을 완료 시 권한부여의 결과로 엑세스 토큰(Access Token)을 발급하고, 이 엑세스 토큰을 이용해 클라이언트는 API(또는 서비스)에 접근 및 서비스를 요청하게 됩니다. 서버는 엑세스 토큰 기반으로 서비스와 권한에 대한 접근 여부를 판단해 데이터를 제공합니다.


OAuth는 현재 2.0 버전을 제공하며, 카카오, 구글, 페이스북에서 OAuth 2.0을 통해 서비스에 대한 인증 및 권한부여를 사용하고 있습니다.


OAuth 2.0에 대한 내용은 자세한 내용은 이 글의 하단 "관련/참고 링크"를 통해 알아볼 수 있습니다.


OAuth 2.0 사용 시 API 인증 흐름

다음 그림은 카카오 API 서비스에 접근하기 위해 OAuth 2.0 인증의 흐름을 7 단계로 나타냅니다.

0, 카카오 서비스를 이용하려면 사전에 앱을 등록 후 앱의 API 키를 발급받아야 합니다.


1, 카카오 서비스에 접근하기 위해 카카오 로그인 페이지를 웹브라우저에 표시합니다.


2, 사용자는 로그인 페이지에 ID, 비밀번호를 입력해 인증을 요청합니다.


3, 카카오 인증서버는 사용자를 인증하고 사용자 인증완료 페이지로 리다이렉션합니다. 이때 인증 코드를 함께 전달합니다.


4, 애플리케이션은 리다이렉션 URL을 분석해 인증코드를 획득합니다.


5, 애플리케이션은 카카오 인증서버에 제대로 인증된 사용자인지 확인 요청을 합니다.


6, 카카오 인증서버는 인증된 사용자임을 확인하고, 엑세스 토큰(Access Token)을 발급합니다.


7, 애플리케이션은 발급받은 엑세스 토큰을 이용해 카카오 API 서버에 접근합니다.



델파이로 OAuth 2.0 구현

위의 API 흐름을 카카오 OAuth와 카카오톡 프로필과 연동하는 과정을 델파이를 통해 구현해봅니다.


다음과 같은 데모를 구현합니다.


구현 과정은 크게 준비 + 3단계로 구분됩니다.

[준비] 카카오 서비스에 앱 등록 및 API 키 발급

[1단계] 인증페이지에 로그인 해 인증코드 취득

[2단계] 인증코드로 엑세스 토큰 취득

[3단계] 엑세스 토큰으로 서비스 접근


[준비] 앱 등록 및 API 키 발급

카카오 서비스를 이용하기 위해서는 사전에 앱을 등록 후 API 키를 발급받는 과정이 필요합니다.
다음 링크를 방문해 앱을 생성하고, REST API 키를 획득합니다.

앱 만들기

앱 이름을 입력하고 [앱 만들기] 버튼을 클릭합니다.

앱을 생성하면 다음 그림과 같이 키가 생성됩니다. 우리는 REST API 키를 사용할 것이므로 REST API 키를 복사해 보관해 둡니다.

하단의 설정 링크를 눌러 상세 설정화면으로 이동합니다.


플랫폼 추가

기본 정보 화면에서 [플랫폼 추가] 버튼을 누릅니다.


웹을 선택하고, 여러분들의 사이트 도메인을 입력합니다. [추가] 버튼을 누릅니다.


사이트 도메인과 Redirect Path를 확인 후 [저장] 버튼을 누릅니다.

사이트 도메인 + Redirect Path(저의 경우 http://hjf.pe.kr/oauth)는 실제 존재하는 페이지를 지정해야 합니다.

이 페이지는 카카오 로그인 후 리다이렉션되는 페이지로 아무 기능이 없더라도 페이지를 생성해 놔야 합니다.(페이지가 없으면 404 not found 오류가 발생합니다.)


운영하는 서비스가 없이 테스트 목적이라면 제 도메인을 등록하도록 합니다.(하지만 언제든 페이지를 삭제할 수 있으니 테스트 목적으로만 사용하시기 바랍니다.)


사용자 관리 활성화

사용자 관리 메뉴로 이동 후, 사용자 관리를 활성화 합니다. 

우리는 카카오 프로필 정보에 접근할 것이므로 프로필 정보 하단의 수집목적을 적절히 입력하고, [설정] 버튼을 클릭합니다.


앱 등록 및 API 키 발급 과정이 완료되었습니다.


[준비] 프로젝트 생성 및 화면 구성

이 예제는 델파이 10.3 리오 버전을 이용해 작성되었습니다. XE5이후 버전에서 문제가 없을것으로 생각됩니다. 다른 버전으로 진행 시 문제가 있다면 댓글을 통해 문의 주시기 바랍니다.

이 예제는 Multi-device Application(FMX 프레임워크)로 작성합니다. VCL Form Application으로 진행 가능하지만, 일부 속성 및 메소드, 이벤트에 차이가 있을 수 있습니다.

File > New > Multi-Device Application 메뉴를 선택 후 Blank Application을 선택 해 프로젝트를 생성합니다.

다음 화면을 참고해 화면을 구성합니다.


[1단계] 로그인 및 인증코드 취득

카카오 인증서버에 로그인 후 인증코드를 받는 과정을 개발합니다.(위의 API 인증 흐름의 1~4 단계 과정입니다.)


카카오 개발가이드 중 사용자 관리-로그인 부분의 문서를 참고해 개발합니다.


[Request]


[Response]


Request와 같이 페에지를 표시 후 사용자 로그인 성공 시 Response와 같이 redirect_url로 페이지 이동됩니다. 이때 인증 코드(authorize_code)가 함께 전달됩니다.


Button1 클릭 이벤트에 다음과 같이 코드를 입력합니다.

procedure TForm1.Button1Click(Sender: TObject);
var
  url: string;
  param: string;
begin
  Edit1.Text := '';

  url := 'https://kauth.kakao.com';
  param := '/oauth/authorize?client_id={app_key}&redirect_uri={redirect_uri}&response_type=code';
  param := param.Replace('{app_key}', API_KEY);
  param := param.Replace('{redirect_uri}', 'http://hjf.pe.kr/oauth');

  WebBrowser1.URL := url + param;
  WebBrowser1.Navigate;
end;

API_KEY는 상수로 implementation 위에 등록했습니다.(앱 생성 시 등록한 REST API 키를 XXXXX 대신 입력합니다.)

const
  // 카카오톡 개발자 사이트에서 앱 등록 후 API키를 등록하세요.
  API_KEY = 'XXXXXXXXXXXXXXXXX';

implementation

로그인 성공 시 인증코드 수신하는 내용을 작성합니다. WebBrowser1의 OnDidFinishLoad(페이지 전환 완료) 이벤트 생성 후 다음 코드를 입력합니다.

procedure TForm1.WebBrowser1DidFinishLoad(ASender: TObject);
var
  url: string;
  code: string;
begin
  Memo1.Lines.Add('WebBrowser1DidFinishLoad' + WebBrowser1.URL);

  if Edit1.Text <> '' then
    Exit;

  url := WebBrowser1.URL;

  if Pos('code=', url) > 0 then
  begin
    code := Copy(url, Pos('code=', url) + Length('code='), Length(url));
    if Pos('&', code) > 0 then
      code := Copy(code, 1, Pos('&', code)-1);

    Edit1.Text := code;
  end;
end;

제일 첫줄은 URL을 메모에 출력하는 로그성 기능입니다.


13~20줄에서 변경된 URL 중 인증코드 파라메터("code=")가 있는 경우 인증코드 값을 가져와 Edit1.Text에 설정합니다.


[2단계] 엑세스 토큰 취득

인증코드를 받은 다음, 이를 이용해 실제로 API를 호출할 수 있는 엑세스 토큰(Access Token)을 받아오는 내용을 구현합니다.


이 부분도 카카오 개발가이드 중 사용자 관리-로그인, 사용자 토큰 받기 부분의 문서를 참고해 개발합니다.


[Request]


[Response]


위 문서와 같이 POST로 요청 후 받은 응답 값(json 포맷)에서 access_token 값을 취득해야 합니다.

이 기능은 REST Client 프레임워크를 이용해 개발합니다.


화면에 TRESTClient, TRESTRequest, TRESTResponse 3개의 컴포넌트를 추가 합니다.


[3. 엑세스 토큰 취득] 버튼의 클릭 이벤트에 다음과 같이 구현합니다.
(아래 과정은 디자인 타임에서 컴포넌트에 직접 설정해도 무관합니다.)

procedure TForm1.Button2Click(Sender: TObject);
var
  token: string;
begin
  RESTClient1.BaseURL := 'https://kauth.kakao.com/';

  RESTRequest1.Resource := 'oauth/token';
  RESTRequest1.Method := rmPOST;
  RESTRequest1.Params.Clear;
  RESTRequest1.Params.AddItem('grant_type',   'authorization_code');
  RESTRequest1.Params.AddItem('client_id',    API_KEY);
  RESTRequest1.Params.AddItem('redirect_uri', 'http://hjf.pe.kr/oauth');
  RESTRequest1.Params.AddItem('code',         Edit1.Text);

  RESTRequest1.Execute;

  Memo1.Lines.Text := RESTResponse1.Content;

  if RESTResponse1.JSONValue.TryGetValue<string>('access_token', token) then
    Edit2.Text := token;
end;

개발가이드와 같이 요청 정보를 RESTClient와 RESTRequest 컴포넌트의 속성과 파라메터에 설정한 후 실행(RESTRequest1.Execute;) 후 받은 응답에서 엑세스 토큰(access_token)을 받아 Edit2.Text에 설정합니다.


엑세스 토큰을 받는 과정까지 마쳤습니다. 이제 엑세스 토큰을 이용해 카카오톡 프로필 정보에 접근해 데이터를 연동 할 수 있습니다.


[3단계] 카카오톡 프로필과 연동

엑세스 토큰을 얻었다면 카카오톡 프로필 서비스와 연동해 프로필 정보를 받아올 수 있습니다.


카카오 개발가이드 중 카카오톡-프로필요청 부분의 문서를 참고해 개발합니다.



[Request]


[Response]


위 문서와 같이 GET으로 요청 후 프로필 정보와 프로필 이미지 정보를 받아올 수 있습니다.
주의사항은 요청 시 Authorization 항목이 포함되어 권한 컴포넌트를 하나더 사용합니다.

화면에 TRESTClient, TRESTRequest, TRESTResponse, TOAuth2Authenticator 4개의 컴포넌트를 추가 합니다.


그리고, 프로필 이미지를 받기 위한 컴포넌트를 화면에 추가합니다.

[4, 카카오톡 프로필 조회] 버튼의 클릭 이벤트에 다음과 같이 구현합니다.

procedure TForm1.Button3Click(Sender: TObject);
var
  Url: string;
  Stream: TMemoryStream;
begin
  OAuth2Authenticator1.AccessToken := Edit2.Text;

  RESTClient2.BaseURL := 'https://kapi.kakao.com/';
  RESTClient2.Authenticator := OAuth2Authenticator1;

  RESTRequest2.Client := RESTClient2;
  RESTRequest2.Response := RESTResponse2;

  RESTRequest2.Resource := 'v1/api/talk/profile';
  RESTRequest2.Execute;

  Memo1.Lines.Text := RESTResponse2.Content;

  Url := RESTResponse2.JSONValue.GetValue<string>('profileImageURL');

  RESTClient3.BaseURL := Url;
  RESTClient3.Authenticator := OAuth2Authenticator1;
  RESTRequest3.ExecuteAsync(procedure
    begin
      Stream := TMemoryStream.Create;
      try
        Stream.WriteData(RESTResponse3.RawBytes, RESTResponse3.ContentLength);
        ImageControl1.Bitmap.LoadFromStream(Stream);
      finally
        Stream.Free;
      end;
    end
  );
end;

6번째 라인에서 권한 컴포넌트에 엑세스 토큰을 설정합니다.


8~17 라인에서 프로필 정보를 요청하고, 응답받은 컨텐츠 내용을 메모에 출력합니다.


19번째 라인에서 프로필 이미지 URL을 추출합니다.


21~33 라인에서는 프로필 이미지를 비동기(Async)로 받아 이미지 컨트롤에 표시합니다.


완료 및 테스트

카카오톡 프로필과 연동하는 예제 구현이 완료되었습니다.

작성한 프로젝트를 실행해 여러분의 카카오 계정을 이용해 테스트 진행할 수 있습니다.

완성된 프로젝트 파일

추가 학습할 내용

카카오 서비스 연동 및 인증(OAuth 2.0)은 REST API 기반으로 구현됩니다. 다음 글들을 통해 REST API를 이해하고 실습할 수 있습니다.
REST 클라이언트에 대한 개념을 아래 글을 통해 습득하실 수 있습니다.

관련/참고 링크


험프리.김현수 데이터 엑세스

RFID 리더(한미IT RF Prisma) 연동하기 - 델파이에서 JAR 이용

2017.12.19 09:17

(아래 내용은 델파이 10.2 도쿄 릴리즈 1과 릴리즈 2에서 작성된 내용으로 다른 버전에서는 일부 내용이 다를 수 있습니다.)


개발 컨설팅을 통해 의뢰한 작업 중 RFID 리더 연동한 내용 공유합니다.

(3일간의 개발 컨설팅으로 RFID 리더, TMAP 연동, 원격 데이터 연동 기술을 전파하는 작업을 진행했습니다.)


RFID 리더와 연동은 제조사에서 제공하는 라이브러리(안드로이드 JAR)를 이용했습니다.

이 과정을 통해 델파이에서 JAR 파일 연동하는 내용을 확인할 수 있습니다.


RFID 리더 연동



위 영상의 RFID 리더는 RFID 태그의 값을 읽고, 바코드의 값을 읽어 안드로이드 앱에 데이터를 전달합니다.

안드로이드 앱은 장비를 구동 및 설정하고, 장비가 읽은 데이터를 받아 화면에 표시합니다.


안드로이드 앱은 델파이(파이어몽키)를 이용해 개발했으며, 장비와 연동하는 부분은 제조사에서 제공한 JAR 형태의 라이브러리를 이용했습니다.


델파이에서 JAR 파일 연동 과정은 아래와 같습니다

1, 작업 준비

2, 델파이용 JAR 브릿지 파일 생성

3, 델파이 프로젝트에 JAR 파일 추가

4, 브릿지 파일로 JAR 연동 코드 작성


기타  참고사항

 - 안드로이드 연동 시 참고사항

 - 프레임을 이용해 재사용 가능한 화면 제작

샘플 프로젝트


작업 준비

대상 장비 - 한미IT RF Prisma


한미IT RF Prisma

제품 링크 : http://www.hanmiit.co.kr/hanmiit/handler/Main-Start


제품 문의

한미IT영업 임상기과장 skyoflsk@hanmi.co.kr


라이브러리 준비 및 분석

위 제품 링크 페이지에서 SDK Download 메뉴를 이용해 SDK 관련 파일을 제공합니다.

(안드로이드, iOS, 윈도우용 라이브러리를 제공합니다. 이글에서는 안드로이드 라이브러리만 다룹니다.)


다운로드 받은 압축파일에는 SDK 파일과 문서, 샘플이 포함되어 있습니다.

(앱스토어에서 RFPrisma로 검색 해 샘플 앱을 설치할 수 있습니다.)

문서와 샘플을 통해 제공하는 기능을 확인하고, 대략적인 사용법을 익히도록 합니다. 특히 라이브러리를 호출하는 부분은 정확히 숙지해야 합니다.


델파이용 JAR 브릿지 파일 생성

델파이에서 JAR 파일을 연동하기 위해 브릿지 파일(JAR 파일에 대한 델파이 인터페이스)을 생성해야 합니다.

브릿지 파일 생성

Java2OP.exe를 이용 델파이 브릿지 파일을 생성합니다. Java2OP는 JAR 파일 또는 Java 소스파일을 호출할 수 있는 델파이 코드를 생성합니다.(참고: 파이어몽키에서 외부 라이브러리 연동하기(jar. so, a))


아래 커맨드를 이용 브리지 파일(Androidapi.JNI.rfidreaderapi.pas)을 생성합니다.
set path=%PATH%;"c:\Program Files (x86)\Embarcadero\Studio\19.0\bin\converters\java2op"

java2op -jar ..\SDK\rfid.reader.api.jar -unit Androidapi.JNI.rfidreaderapi
위 코드를 명령 프롬프트에서 바로 입력 및 실행하거나, 배치파일(*.bat)로 실행할 수 있습니다.
(*.jar 파일의 경로를 상대경로로 입력 시 주의하시기 바랍니다. 절대경로를 이용해도 됩니다.)

델파이 프로젝트에 JAR 파일 추가

라이브러리 추가

멀티-디바이스 애플리케이션(파이어몽키) 프로젝트에서 타겟 플랫폼을 안드로이드로 설정 후 트리를 펼쳐 Libraries 항목에 JAR 파일을 추가해야 합니다.

델파이 브릿지 파일 추가

JAR와 연동하기 위해 델파이 브릿지 파일(Androidapi.JNI.rfidreaderapi.pas)을 프로젝트에 추가합니다.

브릿지 파일 확인을 위해 컴파일 후 오류를 조치합니다.


만약, 컴파일 시 E2029 오류 발생 시 다음을 참고해 조치합니다.

E2029 오류 조치방법

E2029 오류는 예약어를 용도와 다른 곳에서 사용할 경우 발생합니다.

오류가 발생하는 예약어 키워드 앞에 "&"을 추가해 해결합니다.

(예> type -> &type, in -> &in)

(참고: http://tech.devgear.co.kr/delphi_qna/420082)


브릿지 파일로 JAR 연동 코드 작성

JAR와 연동하는 코드는 아래와 같이 클래스를 이용해 작성했습니다.

FMX.HanmiIT.RFIDReader.pas


구현한 내용 중 다음 내용을 살펴보겠습니다.

1, 인스턴스 메소드와 클래스 메소드 접근

2, 자바 이벤트 리스너 설정


인스턴스 메소드와 클래스 메소드 접근

RF Prisma JAR 라이브러리에는 독특하게 클래스 메소드를 많이 사용하도록 구현되어 있습니다.


연동 시 델파이 클래스(TJATRfidManager)는 클래스 인터페이스(JATRfidManagerClass)와 인스턴스 인터페이스(JATRfidManager) 쌍으로 이뤄집니다. 

클래스 인터페이스(JATRfidManagerClass)는 객체를 생성하기 전의 클래스를 통해 접근하는 함수, 속성, 상수를 제공합니다. 자바코드를 사용하는 경우 "델파이클래스명.JavaClass.클래스메소드" 형식으로 JavaClass 속성을 통해 자바 클래스에 접근해야 합니다.

인스턴스 인터페이스(JATRfidManager)는 객체 생성 후 사용가능한 인스턴스 함수와 속성 상수를 제공합니다.

이 라이브러리에는 객체(JATRfidReader 등) 생성 시 아래와 클래스 메소드를 이용합니다. 해당 객체의 추가 기능은 인스턴스 메소드로 제공합니다.
var
  FReader: JATRfidReader;
...
  FReader := TJATRfidManager.JavaClass.getInstance;

  FReader.setEventListener(FEventListener);
  FReader.connectDevice(StringToJString(AAddress));
  FReader.setStoredMode(Value);
  FReader.setReportMode(Value);

자바 이벤트 리스너 설정

연동 시 가장 우려하던 부분입니다. RFID 태그를 읽거나 연결상태 가 변경되는 등 장비에서 동작해 발생하는 이벤트 정보를 리스너(JATRfidEventListener)를 통해 앱에서 받습니다.


리스너 구현시 메인 클래스(TRfidReader)에서 바로 리스너 인터페이스를 위임받아 구현해도 되지만, 복잡해 지기 때문에 별도의 클래스에서 이벤트 리스너를 구현하고 필요한 정보만 받도록  분리해 구현했습니다.


이벤트 리스너 구현 선언부

type
  TRfidEventListner = class(TJavaLocal, JATRfidEventListener)
  private
    FHandler: IRfidEventHandler;
  public
    constructor Create(AHandler: IRfidEventHandler);

    { JATRfidEventListenerClass }
    procedure onAccessResult(P1: JATRfidReader; P2: Jtype_ResultCode; P3: JActionState; P4: JString; P5: JString; P6: Single; P7: Single); cdecl;
    procedure onActionChanged(P1: JATRfidReader; P2: JActionState); cdecl;
    procedure onCommandComplete(P1: JATRfidReader; P2: JCommandType); cdecl;
    procedure onDebugMessage(P1: JATRfidReader; P2: JString); cdecl;
    procedure onDetactBarcode(P1: JATRfidReader; P2: JBarcodeType; P3: JString; P4: JString); cdecl;
    procedure onLoadTag(P1: JATRfidReader; P2: JString); cdecl;
    procedure onReadedTag(P1: JATRfidReader; P2: JActionState; P3: JString; P4: Single; P5: Single); cdecl;
    procedure onRemoteKeyStateChanged(P1: JATRfidReader; P2: JRemoteKeyState); cdecl;
    procedure onStateChanged(P1: JATRfidReader; P2: JConnectionState); cdecl;
  end;

위와 같이 JTARfidEventListener 인터페이스를 위임받고, 해당 인터페이스의 함수를 정의합니다.


주의할 사항은 Create 메소드의 파라메터로 IRfidEventHandler 인터페이스를 받아 FHandler에 저장하도록 구현합니다.


델파이 이벤트 인터페이스 선언부

IRfidEventHandler는 아래와 같이 필요한 메소드만 정의했습니다. 특히 파라메터는 사용하기 편하도록 델파이 자료형으로 재정의 했습니다.

type
  IRfidEventHandler = interface
  ['{FFEB910C-3BB8-48CA-BE11-B09CC07E53AC}']
    // Rfid Reader
    procedure ReadedTag(AReader: JATRfidReader; ATag: string);
    procedure StateChagned(AReader: JATRfidReader; AState: TConnectionState);

    // Barcode
    procedure ActionChagned(AReader: JATRfidReader; AState: TActionState);
    procedure DetactBarcode(AReader: JATRfidReader; ABarcodeType, ACodeId, ABarcode: string);
  end;


메인 클래스에서 델파이 이벤트 인터페이스 위임
위 인터페이스는 메인 클래스에서 위임받았고, 이벤트 핸들러 생성 시 파라메터로 전달합니다.
그리고, FReader 객체에 이벤트 리스너를 설정(setEventListener)합니다.
type
  TRFIDReader = class(TInterfacedObject, IRfidEventHandler)
...
procedure TRFIDReader.InitReader;
begin
...
  FEventListener := TRfidEventListner.Create(Self);
...
  FReader := TJATRfidManager.JavaClass.getInstance;
  FReader.setEventListener(FEventListener);
end;

이벤트 발생 시 델파이 이벤트 인터페스를 통해 전달
JATRfidEventListener에서 이벤트 발생 시 IRfidEventHandler에 이벤트를 전달하도록 구현했습니다.
procedure TRfidEventListner.onStateChanged(P1: JATRfidReader;
  P2: JConnectionState);
var
  State: TConnectionState;
begin
  if Assigned(FHandler) then
  begin
    State := TConnectionState.Disconnected;
    if P2.getState = TJConnectionState.JavaClass.Connected.getState then
      State := TConnectionState.Connected
    else if P2.getState = TJConnectionState.JavaClass.Connecting.getState then
      State := TConnectionState.Connecting
    else if P2.getState = TJConnectionState.JavaClass.Listen.getState then
      State := TConnectionState.Listen
    ;

    FHandler.StateChagned(P1, State);
  end;
end;

이후 이벤트 정보를 받은 메인 클래스에서 비지니스 로직을 수행하도록 구현합니다.

기타 참고사항

안드로이드 연동 시 참고사항

가장 좋은 참고자료는 파이어몽키에 구현된 안드로이드 연동한 내용을 참고하는 것입니다.

(델파이 정품 설치 시 설치경로 하위의 source 디렉토리에는 파이어몽키 라이브러리 소스코들이 포함되어 있습니다.)


그중 다음 소스코드들을 참고하면 아주 좋습니다.

안드로이드 SDK 브릿지 파일

기본 안드로이드 SDK 델파이 브릿지 파일이 아래 경로에 포함되어 있습니다.
  • C:\Program Files (x86)\Embarcadero\Studio\19.0\source\rtl\android - 10.2 도쿄 기준

파이어몽키 라이브러리

파이어몽키 컴포넌트와 라이브러리 등을 어떻게 구현했는지 아래 경로의 파일들에서 살펴볼 수 있습니다.

  • C:\Program Files (x86)\Embarcadero\Studio\19.0\source\fmx - 10.2 도쿄 기준


프레임을 이용해 재사용 가능한 화면 제작

일부 기능적인 화면들이 필요한데 다른 프로젝트에서도 활용할 만한 기능들이어서 재사용 가능하도록 구현해봤습니다.

libs 디렉토리에 포함된 3개의 프레임입니다.

  • FMX.UI.OverflowMenu.pas - 메인 화면의 우측 상단의 연결 팝업 메뉴 구현
  • FMX.UI.SelectBluetoothDeviceDialog.pas - 블루투스 장비를 탐색 후 장비 선택 정보 제공하도록 구현
  • FMX.UI.WaitDialog.pas - 비동기로 진행하는 블루투스 장비 연결을 기다리는 화면
프레임을 사용한 이유는 화면의 일부 영역을 표현하기 위함입니다.
프레임은 화면을 포함한 객체입니다.(Create, Destroy, Show, Hide 이벤트 등을 제공하지 않아 필요한 경우 직접 구현해야 합니다.)
화면등에서 객채 생성하는 코드를 줄이기 위해 클래스 메소드로 기능 호출하도록 구현했습니다.

클래스 메소드로 기능화면 호출
위 유닛 파일을 유즈절(uses)에 추가 후 아래와 같이 기능을 호출할 수 있습니다.
  TWaitDialog.Show('블루투스를 활성화 합니다.', 2000);

  TOverflowMenu.Settings.Top := ToolBar1.Height + 1;
  TOverflowMenu.Settings.Width := Width * 0.9;
  TOverflowMenu.Settings.RightPadding := 10;
  TOverflowMenu.ShowMenu([
      'Connect to last bluetooth device',
      'Connect to new bluetooth device'],
    procedure(AIndex: Integer; AText: string)
    begin
      case AIndex of
        0: ConnectToLastDevice;
        1: ConnectToNewDevice;
      end;
    end);

자세한 별도의 글을 통해 소개하도록 하겠습니다.(그 전에는 직접 소스코드를 통해 내용을 확인하시기 바랍니다.)

기타 궁금한 내용은 댓글 또는 http://blog.hjf.pe.kr/482의 댓글을 참고하거나 등록해 주세요.


험프리.김현수 파이어몽키

  1. 블루투스 바코드 스캐너(BI-07) 안드로이드 라이브러리를 델파이에서 연동하는 방법( http://blog.hjf.pe.kr/452 )도 참고하시기 바랍니다.

  2. Blog Icon
    주만지

    와와와.. 저희 회사도 rfid 연동하는데 시간 날때 한번 해봐야 겠어여
    한국엔 라드 자료가 많이 없는데 우연히 구글링하다 들어와서 잘 보고 갑니다^^*
    네이버라면 친추하겠는데,,ㅠ
    혹시 가끔 모르는 거 들어와서 여쭤 봐도 될까요? ㅋ

WaitDialog 구현 - 재사용 가능한 프레임 구현하기

2017.12.06 13:36

얼마전 진행한 모바일 개발 컨설팅에서 블루투스 장비와 연결 후 기다리는 동안 표시할 화면이 필요했습니다.

WaitDialog라는 화면을 만들었는데 이 화면은 앞으로도 많이 사용하게 될 것 같아 TFrame을 이용해 재사용 가능하도록 구현해 봤습니다.


WaitDialg 구현에 아래 기술을 사용했습니다.

1) TFrame

2) 클래스 메소드

3) 싱글톤 패턴


이 내용을 학습하면

1) 자주 사용하는 화면을 프레임으로 제작 해 재사용 할 수 있습니다.

2) 클래스 메소드를 활용해 코드를 짧게 사용 할 수 있습니다.

결과화면

결과 화면은 아래와 같습니다.


구현한 내용

화면구성

파이어몽키 프레임을 이용해 WaitDialog 화면을 구성했습니다.

파이어몽키에서 TFrame은 폼디자이너에서 화면을 구성할 수 있는 객체입니다. UI 컴포넌트와 논비주얼 컴포넌트를 화면에 추가하고 사용할 수 있습니다.


WaitDialog 코드

type
  TWaitDialog = class(TFrame)
    rctBackground: TRectangle;
    lytMessage: TLayout;
    rctMessageBG: TRectangle;
    lblMessage: TLabel;
    AniIndicator1: TAniIndicator;
    Timer: TTimer;
    procedure TimerTimer(Sender: TObject);
  private
    class var FInstance: TWaitDialog;
  private
    { Private declarations }
  public
    { Public declarations }
    destructor Destroy; override;

    class procedure Show(ATitle: string = ''; ATimeout: Integer = -1);
    class procedure Hide;
  end;

implementation

{$R *.fmx}

{ TFrame1 }

class procedure TWaitDialog.Show(ATitle: string; ATimeout: Integer);
begin
  if not Assigned(FInstance) then
    FInstance := Create(nil);

  FInstance.Parent := Application.MainForm;
  FInstance.Align := TAlignLayout.Client;
  FInstance.BringToFront;
  FInstance.Visible := True;

  if ATitle <> '' then
  begin
    FInstance.lblMessage.Text := ATitle;
  end;

  if ATimeout > 0 then
  begin
    if ATimeout < 1000 then
      ATimeout := 1000;
    FInstance.Timer.Interval := ATimeout;
    FInstance.Timer.Enabled := True;
  end;
end;

class procedure TWaitDialog.Hide;
begin
  if not Assigned(FInstance) then
    Exit;
  FInstance.Visible := False;
  FInstance.DisposeOf;
end;

procedure TWaitDialog.TimerTimer(Sender: TObject);
begin
  Timer.Enabled := False;
  Hide;
end;

destructor TWaitDialog.Destroy;
begin
  FInstance := nil;

  inherited;
end;

initialization
finalization
  TWaitDialog.Hide;

클래스 메소드

WaitDialog를 보여주고 감추는 메소드(Show, Hide)를 클래스 메소드(class procedure, class function)로 구현했습니다.

클래스 메소드는 클래스를 생성하기 전에 호출할 수 있는 메소드로 Create 등이 대표적인 클래스 메소드입니다.


클래스 메소드를 사용한 이유는 WaitDialog를 호출하는 측의 코드를 최대한 짧게 작성할 수 있도록 하기위해서 입니다.


싱글톤 패턴

클래스 메소드를 사용 후 객체를 생성하기 위해 클래스 변수(class var)를 사용했습니다. 


객체 생성은 Show 메소드에서, 객체 해제는 Hide 메소드에서 합니다. Hide 시키지 않고 앱을 종료하는 경우를 대비 finalization에서 Hide 메소드를 호출 합니다.


싱글톤 패턴은 프로그램 내에서 객체를 하나만 생성하는 디자인 패턴입니다. 위 예제에서 객체는 하나만 생성합니다.

만약, 다른 곳에서 싱글톤 객체가 필요하다면 아래와 같은 코드를 추가할 수 있습니다.

class function TWaitDialog.Instance: TWaitDialog; begin if not Assigned(FInstance) then FInstance := Create; Result := FInstance; end; class procedure TWaitDialog.ReleaseInstance; begin if Assigned(FInstance) then FInstance.DisposeOf; end; initialization finalization TWaitDialog.ReleaseInstance;

위와 같이 구현하면 TWaitDialog.Instance를 이용해 접근하면 객체를 유일하게 사용할 수 있습니다.(너무 멀리까지 나갔네요.^^)

사용방법

uses FMX.WaitDialog;

  TWaitDialog.Show;
  TWaitDialog.Show('잠시만 기다려 주세요.');
  TWaitDialog.Show('잠시만 기다려 주세요.', 10000);

  TWaitDialog.Hide;

uses 절에 유닛을 추가하고, Show 클래스 메소드를 다양한 방식으로 호출해 화면을 표시합니다.

비동기 동작이 완료된 경우 Hide 클래스 메소드를 호출하면 화면이 감춰집니다.


데모 프로젝트

WaitDialog.zip


험프리.김현수 파이어몽키

[튜토리얼] 메일 전송(IdSMTP 이용)

2017.11.22 14:27

IdSMTP, IdMessage를 이용 메일 전송 예제


참고코드

procedure TForm2.Button1Click(Sender: TObject);
begin
  SMTP.Host := ''; // host address
  SMTP.Port := 25;

  MailMessage.From.Address := ''; // From email address
  MailMessage.Recipients.EMailAddresses := Edit2.Text;//'hskim@embarcadero.kr';

  MailMessage.Subject := Edit1.Text;
  MailMessage.Body.Text := Memo1.Lines.Text;
  MailMessage.CharSet := 'UTF-8';
  SMTP.Connect;
  SMTP.Send(MailMessage);
  if SMTP.Connected then
    SMTP.Disconnect;

  ShowMessage('');
end;

샘플 프로젝트

SendMail.zip


문단제목




험프리.김현수 Delphi/C++Builder

  1. 파일 첨부
    // uses IdAttachmentFile;
    MailMessage.MessageParts.Clear;
    TIdAttachmentFile.Create(MailMessage.MessageParts, Filename);

  2. 감사합니다 ~~~

[튜토리얼] FTP 업로드(TIdFTP 이용)

2017.11.22 14:24

IdFTP를 이용 로컬 파일을 서버로 업로드하는 예제

  • 로컬파일 선택
  • 업로드 시 프로그레스바로 진행률 표시

참고 코드

procedure TForm2.Button1Click(Sender: TObject);
begin
  if OpenDialog1.Execute then
    Edit1.Text := OpenDialog1.FileName;
end;

procedure TForm2.Button2Click(Sender: TObject);
var
  LocalPath, RemotePath: string;
begin
  LocalPath := Edit1.Text;
  RemotePath := 'test/' + ExtractFileName(LocalPath);

  IdFTP1.Host := 'hjf.pe.kr';
  IdFTP1.Port := 21;
  IdFTP1.Passive := True;
  IdFTP1.Username := '';  // FTP user
  IdFTP1.Password := '';  // FTP password
  IdFTP1.Connect;

  IdFTP1.Put(LocalPath, RemotePath);

  IdFTP1.Disconnect;
end;

procedure TForm2.IdFTP1Work(ASender: TObject; AWorkMode: TWorkMode;
  AWorkCount: Int64);
begin
  ProgressBar1.Position := AWorkCount;
end;

procedure TForm2.IdFTP1WorkBegin(ASender: TObject; AWorkMode: TWorkMode;
  AWorkCountMax: Int64);
begin
  ProgressBar1.Max := AWorkCountMax;
end;

샘플 프로젝트

IdFTPUpload.zip


문단제목





험프리.김현수 Delphi/C++Builder

델파이/C++빌더에 TTcpClient, TTcpServer, TUdpSocket 등록하기

2017.11.02 14:30

TTcpClient, TTcpServer, TUdpSocket 컴포넌트 들이 어느 버전에서 부터인지 모르지만, 기본 컴포넌트에서 빠져있습니다.


위 3개 소켓 컴포넌트를 등록하는 방법을 안내합니다.

(이 글은 RAD Studio 10.2 도쿄 버전을 기준으로 안내합니다.)


1, 윈도우 탐색기로 열고 다음 경로(기본 샘플 경로)로 이동합니다.

C:\Users\Public\Documents\Embarcadero\Studio\19.0\Samples\Object Pascal\VCL\InetWinSockets


2, RAD Studio에서 "inetwinsockets.dpk" 프로젝트를 엽니다.


3, 프로젝트 매니저의 팝업 메뉴에서 Install 메뉴를 선택 해 설치합니다.


4, 델파이 라이브러리 패스에 위 경로를 추가합니다. 

(또는 "Web.Win.Sockets.pas"를 델파이 라이브러리 패스에 포함된 곳에 복사합니다.)


5, 툴팔렛트의 "Internet" 카테고리에 컴포넌트 추가를 확인합니다.


만약, 컴포넌트 추가 후 컴파일 시 "Web.Win.Sockets" 유닛을 찾을 수 없다면 4 단계(라이브러리 패스에 추가)를 검토하시기 바랍니다.


관련링크







험프리.김현수 분류없음

안면인식(Face Detection) 라이브러리(안드로이드, iOS)

2017.10.30 15:02

델파이 개발 그룹인 grijjy 팀(블로그: https://blog.grijjy.com/)에서 안면인식(Face Detection) 라이브러리를 공개했습니다.


이 라이브러리리는 안드로이드와 iOS에 내장된 사진에서 얼굴을 감지하는 기능을 이용해, 하나의 라이브러리로 제공합니다.


안면인식 기술 개발이 필요하거나, 여러 플랫폼 기능을 하나의 라이브러리로 개발하고자 하는 경우 참고하면 아주 좋습니다.


안면인식(안드로이드, iOS)

  • https://blog.grijjy.com/2017/09/11/face-detection-on-android-and-ios/


험프리.김현수 Delphi/C++Builder

TTS(Text-to-Speech) 라이브러리(윈도우, 맥OS, iOS, 안드로이드)

2017.10.30 14:52

델파이 개발 그룹인 grijjy 팀(블로그: https://blog.grijjy.com/)에서 문자를 읽어주는 TTS(Text-to-speech) 라이브러리를 공개했습니다.


이 라이브러리는 윈도우, 맥OS, iOS, 안드로이드를 지원합니다.

(grijjy 팀에서 크로스 플랫폼 추상화 레이어 설계를 연습하기 위해 제작했으며, 각 플랫폼 API TTS 기능을 하나의 라이브러리(컴포넌트)로 제공합니다.)


해당 기능이 필요하거나, 공통된 여러 플랫폼의 API를 하나의 라이브러리(컴포넌트)로 제작하는 방법을 참고하면 아주 좋겠습니다.


Cross Platform Text-to-Speech

참고




험프리.김현수 Delphi/C++Builder

델파이로 빅데이터 데이터베이스 연동하기(Cassandra, Couchbase, MongoDB)

2017.10.30 14:32

델파이 개발 그룹인 grijjy 팀(블로그: https://blog.grijjy.com/)에서 빅데이터 데이터베이스에 직접 연동해 작업할 수 있는 델파이 라이브러리를 오픈소스로 공개하였습니다.


카산드라(Cassandra), 카우치베이스(Couchbase), 몽고DB(MongoDB) 총 3개의 빅데이터 데이터베이스 접근용 라이브러리이며, 해당 글에서는 친절하게 설치방법과 샘플 코드등을 자세히 설명합니다.


빅데이터 연동에 이슈가 있거나 관심이 있는 분들에게 큰 도움이 될 것으로 보입니다.

자세한 내용은 아래 링크를 통해 (영문으로)자세히 볼수 있습니다.


참고로, 몽고DB의 경우 델파이에 기본 내장된 FireDAC을 이용해 직접 접속할 수도 있습니다.

(하단에 관련 링크를 추가합니다.)


카산드라(Cassandra)

카산드라는 구글의 BigTable 컬럼 기반의 데이타 모델과 FaceBook에서 만든 Dynamo의 분산 모델을 기반으로 하여 제작되어 Facebook에 의해 2008년에 아파치 오픈소스로 공개된 분산 데이타 베이스 입니다. 
출처: http://bcho.tistory.com/440 [조대협의 블로그]

카우치베이스(Couchbase)

카우치베이스 서버(Couchbase Server)는 유연한 JSON 모델로 고정 데이터베이스 스키마의 제약 없이 쉽게 애플리케이션을 수정할 수 있으며, submilisecond (1/1000 ms 이하)의 초고속 데이터 입출력 처리의 높은 성능을 보장합니다. 또한, 간편한 스케일 아웃(scale-out)으로 다운타임 없이 시스템 구성 변경 및 확장을 지원합니다.

몽고DB(MongoDB)

몽고DB(MongoDB←HUMONGOUS)는 크로스 플랫폼 도큐먼트 지향 데이터베이스 시스템이다. NoSQL 데이터베이스로 분류되는 몽고DB는 JSON과 같은 동적 스키마형 문서들(몽고DB는 이러한 포맷을 BSON이라 부름)을 선호함에 따라 전통적인 테이블 기반 관계형 데이터베이스 구조의 사용을 삼간다. 이로써 특정한 종류의 애플리케이션을 더 쉽고 더 빠르게 데이터 통합을 가능케 한다.


참고로, 

몽고DB는 델파이에 기본 내장된 FireDAC을 통해 직접 연동할 수 있습니다.


험프리.김현수 Delphi/C++Builder

[FMX] TListView 더보기 버튼 구현하기

2017.09.20 13:49

모바일 앱을 개발할 때에 리스트 항목이 많은 경우, 한번에 가져오면 시간이 오래 걸려 좋지 않은 사용자 경험이 됩니다.


이 경우, 리스트 중 일부를 빠르게 표시하고, 리스트 끝으로 이동 시 추가로 표시하는 방식을 통해 문제를 해결할 수 있습니다.


이 글에서는, 

리스트뷰(TListView)의 목록 끝으로 이동 시, 더보기 버튼을 표시하도록 (매우 심플하게)구현합니다.

버튼 클릭 시 항목을 추가합니다.


이 글을 참고해 리스트 끝으로 이동 시 자동으로 항목을 추가하도록 구현할 수도 있습니다.


리스트뷰 더보기 버튼  구현하기

결과

결과 화면은 다음과 같습니다.


처음 24개 항목 표시 후, 목록 끝으로 이동 시 버튼이 표시되고, 버튼을 눌러 항목을 추가합니다.


구현방법

1) 더보기 버튼을 리스트뷰(TListView)에 올려놓고 감춥니다.(Visible := False)

2) 리스트뷰의 스크롤 이동(OnScrollViewChange) 이벤트 핸들러에서 제일 끝으로 이동한 경우 버튼을 표시합니다.


컴포넌트 구성은 아래와 같습니다.


구현된 주요 코드는 아래와 같습니다.

procedure TForm2.AddItem(ACount: Integer);
var
  I: Integer;
  Item: TListViewItem;
begin
  for I := 0 to ACOunt - 1 do
  begin
    Item := ListView1.Items.Add;
    Item.Text := 'Item ' + ListView1.Items.Count.ToString;
  end;
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
  AddItem(24);
  btnListViewMore.Visible := False;
end;

procedure TForm2.btnListViewMoreClick(Sender: TObject);
begin
  AddItem(6);
  btnListViewMore.Visible := False;
end;

procedure TForm2.ListView1Resized(Sender: TObject);
begin
  ListView1ScrollViewChange(Sender);
end;

procedure TForm2.ListView1ScrollViewChange(Sender: TObject);
var
  LastItemBottom, ListViewBottom: Single;
begin
  LastItemBottom := ListView1.GetItemRect(ListView1.ItemCount - 1).Bottom;
  ListViewBottom := ListView1.LocalRect.Bottom;

  btnListViewMore.Visible := ((LastItemBottom - ListViewBottom) < 30);
end;


샘플 프로젝트

ListViewMoreButton.zip


이 샘플에서는 더보기 버튼 클릭 시 단순하게 목록을 추가했습니다. 실무에서는 더보기 버튼 클릭시 추가 데이터를 수신 후 목록을 동적으로 갱신하도록 구현해야 합니다.


당겨서 새로고침(Pull to refresh) 구현하기

모바일 앱에서는 새로운 정보를 가져오기 위해 당겨서 새로고침 기능을 사용할 수 있습니다.

이 기능은 리스트뷰(TListView)의 속성을 이용해 구현할 수 있습니다.


PullToRefresh 속성을 True로 설정 시, 목록 상단에서 당겨서 새로고침 기능을 제공합니다.

위 동작이 발생하면 OnPullRefresh 이벤트가 발생합니다.


참고링크


험프리.김현수 파이어몽키

[REST API] 다음 Kakao > 로컬 > 주소검색 연동하기

2017.09.18 15:06

다음 등의 포털 사에서는 자사 데이터 일부를 Open API로 공개하고 있습니다.

특히 지도나 주소, 검색 등은 직접 데이터를 수집하는 것보다 포털의 데이터를 활용하는 것이 개발 및 유지보수에 유리할 수 있습니다.


오늘은 데브기어 테크게시판을 통해 다음 카카오의 주소검색 API 연동을 문의주셔서 해당 내용을 공유합니다.


아래 샘플을 REST API를 이용해 카카오 주소 검색 Open API와 연동하는 내용입니다.

(카카오 Open API의 대부분은 REST API를 제공합니다. )


해당 내용을 잘 익혀서 다양한 Open API를 여러분의 앱에서 활용하실 수 있습니다.


카카오 개발자 > 로컬 : https://developers.kakao.com/docs/restapi/local


카카오 Open API를 연동하기 위해서는 앱을 등록하고, 앱 키를 받아야 합니다.(해당 내용의 설명은 생략합니다.)

카카오 개발자 > 내 애플리케이션 : https://developers.kakao.com/apps


위 링크를 참고해 개발했으며, 제일 문제가 됐던 부분은 HTTP 해더에 Authorization 값을 추가하는 부분입니다.


연동한 결과는 아래와 같습니다.


주요 코드는 아래와 같습니다.

uses
  REST.TYpes;

const
  API_KEY = '';
{
  https://developers.kakao.com/ 등록 > 앱 생성 > 앱키(REST API 키)를 위(API_KEY)에 입력
}

procedure TForm2.Button1Click(Sender: TObject);
begin
  RESTRequest1.Params.ParameterByName('query').Value := Edit1.Text;

  RESTRequest1.Execute;
end;

procedure TForm2.FormCreate(Sender: TObject);
var
  Param: TRESTRequestParameter;
begin
  RESTClient1.BaseURL := 'https://dapi.kakao.com';
  RESTClient1.Accept := 'application/json, text/plain; q=0.9, text/html;q=0.8,';
  RESTClient1.AcceptCharset := 'UTF-8, *;q=0.8';

  RESTRequest1.Resource := 'v2/local/search/address.json?query={query}';
  Param := RESTRequest1.Params.AddHeader('Authorization', 'KakaoAK ' + API_KEY);
  Param.Options := [TRESTRequestParameterOption.poDoNotEncode];

  RESTResponseDataSetAdapter1.RootElement := 'documents';
end;

샘플 프로젝트

KakaoLocalLocation.zip


문단제목



험프리.김현수 Delphi/C++Builder

[FMX] 폼의 높이를 애니메이션으로 변경하기, 툴바를 끌어 폼 이동하기

2017.09.12 15:59

약국용 라디오 어플을 개발하는 개발사에서는, 오래전부터 PC 기반으로만 라디오 서비스를 하고 있습니다.

해당 개발사에서는 노후된 앱을 최신 운영체제(윈도우 10 등) 지원과 모바일 확장을 위해 파이어몽키로 재개발 중입니다.

(파이어몽키는 윈도우, OSX, iOS, 안드로이드를 하나의 소스코드로 개발할 수 있습니다.)


개발 중 몇가지 질문을 주셔서 기술지원 후 해당 내용 일부를 공유합니다.


이 글에서는 다음 내용의 구현 방법을 소개합니다.

1, 폼의 일부영역 보이기/가리기(Collapse)

2, Border가 없는 폼에서 특정영역(Toolbar)을 마우스로 이동하기


결과 화면은 아래와 같습니다.

1, 폼의 일부영역 보이기/가리기(Collapse)

이 기능은 TFloatAnimation 컴포넌트를 사용해 손쉽게 구현할 수 있었습니다.

(파이어몽키에는 애니메이션과 효과를 기본 컴포넌트로 제공합니다.)


TFloatAnimation은 지정 된 시작과 끝 Float 값에 대해 애니메이션 되면 값이 변경할 수 있어, 크기, 위치, 각도, 투명도 등을 천천히 변경할 수 있습니다.


하지만, 폼의 높이(Height) 속성에는 FloatAnimaion을 지정할 수 없어, 폼에 레이아웃 컴포넌트를 놓고, 레이아웃 컴포넌트의 높이를 변경시키고, 변경 시 발생하는 OnProcess 이벤트에서 폼의 높이를 조정하도록 구현했습니다.


위 기능의 코드는 아래와 같습니다.

procedure TForm2.FormCreate(Sender: TObject);
begin
  Self.BorderStyle := TFmxFormBorderStyle.None;

  FOrgHeight := lytMain.Height;
end;

procedure TForm2.Button1Click(Sender: TObject);
begin
  lytMain.Align := TAlignLayout.None;
  FloatAnimation1.Duration := 0.5;
  if lytMain.Height = 0  then
  begin
    FloatAnimation1.StartValue := 0;
    FloatAnimation1.StopValue := FOrgHeight;
    FloatAnimation1.Start;
  end
  else
  begin
    FOrgHeight := lytMain.Height;
    FloatAnimation1.StartValue := FOrgHeight;
    FloatAnimation1.StopValue := 0;
    FloatAnimation1.Start;
  end;
end;

procedure TForm2.FloatAnimation1Finish(Sender: TObject);
begin
  lytMain.Align := TAlignLayout.Client;
end;

procedure TForm2.FloatAnimation1Process(Sender: TObject);
begin
  // 레이아웃 크기 조정 시 폼의 크기 조정
  Self.Height := Trunc(ToolBar1.Height + lytMain.Height) + 1;
end;


2, Border가 없는 폼에서 특정영역을 마우스로 이동하기

테두리가 없는 폼에서 제목등의 특정영역을 마우스로 끌어 이동하기 위해 다음 코드를 사용했습니다.

(해당 코드는 윈도우와 OSX(맥)에서 모두 동작합니다.)

procedure TForm2.ToolBar1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Single);
begin
  if (Button = TMouseButton.mbLeft) then StartWindowDrag;
end;




험프리.김현수 파이어몽키

[FMX] iOS 시스템 볼륨 제어하기

2017.09.08 15:21

엠바카데로 블로그에 HARUYUKI MOHRI가 작성한 C++빌더로 iOS 시스템 볼륨 제어하는 내용이 있어 델파이로 작업해 봤습니다.


원글 : https://community.embarcadero.com/blogs/entry/how-to-control-the-system-audio-volume-of-ios?utm_source=Facebook_Organic&utm_medium=social


아래와 같이 Up/Down 버튼을 누르면 시스템 볼륨을 제어합니다.




MPVolumeView 클래스(iOSapi.MediaPlayer.pas)와 UISlider 클래스(iOSapi.UIKit.pas)를 사용했습니다.


uses 절에 "iOSapi.MediaPlayer, iOSapi.UIKit" 추가해야 합니다.


다음 2개 변수를 선언해야 합니다.

  private
    { Private declarations }
    FMPVolumeView: MPVolumeView;
    FSlider: UISlider;

구현된 델파이 코드는 아래와 같습니다.

procedure TForm1.FormCreate(Sender: TObject);
var
  I, J: Integer;
begin
  FMPVolumeView := TMPVolumeView.Create;

  I := 0;
  J := FMPVolumeView.subviews.count;

  if I = J then
  begin
    log.d('');
  end;

  if FMPVolumeView.subviews.count > 0 then
  begin
    FSlider := TUISlider.Wrap(FMPVolumeView.subviews.objectAtIndex(0));
    FSlider.setValue(0.0);
  end;
end;

procedure TForm1.btnVolumeUpClick(Sender: TObject);
var
  Vol: Single;
begin
  Vol := FSlider.value;
  FSlider.setValue(Vol + 0.1);
end;

procedure TForm1.btnVolumeDownClick(Sender: TObject);
var
  Vol: Single;
begin
  Vol := FSlider.value;
  FSlider.setValue(Vol - 0.1);
end;


샘플 프로젝트

iOSVolumeControl.zip


참고 링크

험프리.김현수 분류없음