보라코딩

Day 17, C# (WPF로 카카오 API 연동) 본문

개발자가 되었다?

Day 17, C# (WPF로 카카오 API 연동)

new 보라 2023. 9. 7. 19:07

C#과 WPF를 이용한 매우 재밌는 강의를 찾았다.

API 사용해서 흥미로움..!

이해 하지 못한 코드는 Chat GPT 통해서 공부했다 ㅎ.ㅎ

 

 

 

 

 


 

 

 

 

결과물

 

 

 

 

 

코드

 

 

 

api.xaml
<Window x:Class="HelloWorld1_WPF_.api"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:HelloWorld1_WPF_"
        mc:Ignorable="d"
        Title="api" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="9*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="2*"/>
            <ColumnDefinition Width="8*"/>
            <ColumnDefinition Width="2*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <TextBlock VerticalAlignment="Center" HorizontalAlignment="Right">검색어 : </TextBlock>
        <TextBox Name="tbox_query" Margin="5,0,5,0" Grid.Column="1" Background="Lavender" VerticalAlignment="Center" />
        <Button Name="btn_search" IsDefault="True" Click="Button_Click" Content="검색" Grid.Column="2" VerticalAlignment="Center"></Button>
        <ListBox Name="lbox_locale" SelectionChanged="ListBox_SelectionChanged" Grid.Row="1" Background="Pink"/>
        <WebBrowser Name="wb" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="3" 
                    Source="http://ehpub.co.kr/kakaomap.html"/>
    </Grid>
</Window>

 

 

 

api.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace HelloWorld1_WPF_
{
    /// <summary>
    /// api.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class api : Window
    {
        public api()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            List<MyLocale> mls = KakaoAPI.Search(tbox_query.Text);
            lbox_locale.ItemsSource = mls;
        }

        private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (lbox_locale.SelectedIndex == -1)
            {
                return;
            }
            MyLocale ml = lbox_locale.SelectedItem as MyLocale; // as는 형변환 시도

// wb는 WebBrowser name
// InvokeScript는 JavaScript 함수를 호출
            object[] ps = new object[] {ml.Lat, ml.Lng};
            wb.InvokeScript("setCenter", ps);
        }
    }
}

 

 

 

MyLocale.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HelloWorld1_WPF_
{
    internal class MyLocale
    {
        internal string Name
        {
            get;
            private set;
        }

        internal double Lat
        {
            get;
            private set;    
        }

        internal double Lng
        {
            get; 
            private set;
        }

        internal MyLocale(string name, double lat, double lng)
        {
            Name = name;
            Lat = lat;
            Lng = lng;
        }

        public override string ToString()
        {
            return Name;
        }
    }
}

 

 

 

KakaoAPI.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web.Script.Serialization;

namespace HelloWorld1_WPF_
{
    static class KakaoAPI
    {
        internal static List<MyLocale> Search(string query)
        {
            List<MyLocale> mls = new List<MyLocale>();

            // Kakao API 장소 검색 엔드포인트 URL
            string site = "https://dapi.kakao.com/v2/local/search/keyword.json";
            string rquery = string.Format("{0}?query={1}", site, query);

            // 웹 요청 생성
            // WebRequest 통해 Get 방식으로
            WebRequest request = WebRequest.Create(rquery);
            
            string rkey = "본인의 키 !!!!!!!!!!!!!!!!!!!!!!"; //REST API KEY
            string header = "KakaoAK " + rkey;
            request.Headers.Add("Authorization",header);

            // 웹 요청을 보내고 응답 받기
            WebResponse response = request.GetResponse();
            Stream stream = response.GetResponseStream();
            StreamReader reader = new StreamReader(stream, Encoding.UTF8);
            String json = reader.ReadToEnd(); //json 방식 사용하려면 참조추가(web.extensions)

            // JSON 데이터를 파싱하기 위해 직렬화 사용
            JavaScriptSerializer js = new JavaScriptSerializer();
            dynamic dob = js.Deserialize<dynamic>(json);
            dynamic docs = dob["documents"];
            object[] buf = docs;
            int length = buf.Length;

            // 검색 결과를 리스트에 추가
            for (int i = 0; i < length; i++)
            {
                string lname = docs[i]["place_name"];
                double x = double.Parse(docs[i]["x"]);
                double y = double.Parse(docs[i]["y"]);

                mls.Add(new MyLocale(lname, y, x));
            }
            // 결과 리스트 반환
            return mls;
        }
    }
}

 

 

 


 

코드 공부하기

 

 

카카오 검색 API 
 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

 

별도로 포맷을 지정하지 않은 경우 응답은 JSON 형식으로 반환됩니다.

 

 

 

 

 

 

 

앱 REST API 키를 헤더에 담아 GET 으로 요청

 

 

 

 

 

 

 

 

 

웹 요청을 보내고, 웹 서버로부터 받은 JSON 응답을 문자열로 읽어옴

 

 

WebResponse response = request.GetResponse();

- WebRequest 객체 : 웹 서버에 실제 HTTP 요청을 보내고, 서버로부터의 응답을 받아옴

- GetResponse 메서드를 호출 : 실제 웹 요청이 서버에 전송되고 서버로부터의 응답을 받아옴

 


Stream stream = response.GetResponseStream();

- 웹 서버로부터 받은 응답 데이터를 읽기 위한 Stream 객체를 생성

- HTTP 응답은 데이터 스트림으로 전송되므로 스트림을 사용하여 데이터를 읽을 수 있음

- GetResponseStream 메서드 : 응답의 데이터 스트림을 가져옴

 

 


StreamReader reader = new StreamReader(stream, Encoding.UTF8);

- StreamReader : 인코딩 방식을 사용하여 스트림에서 텍스트 데이터를 읽기 위한 도구

- UTF-8 인코딩을 사용하여 stream에서 텍스트 데이터를 읽기 위한 reader 객체를 생성

 

 


String json = reader.ReadToEnd();

- HTTP 응답에서 받은 JSON 형식의 데이터를 문자열로 읽는 단계

- reader를 사용하여 데이터 스트림에서 텍스트 데이터를 끝까지 읽고, 이를 문자열로 변환하여 json 변수에 저장

- 이후에 이 문자열을 JSON 파서로 파싱하여 원하는 데이터를 추출할 수 있습니다.



 

 

 

 

 

 

JSON 데이터를 C#에서 사용 가능한 형태로 변환하고, 필요한 데이터를 추출

 

JavaScriptSerializer js = new JavaScriptSerializer();

- JSON 데이터를 파싱하기 위해 JavaScriptSerializer 객체를 생성

* 참고) JSON 파싱 : JSON 문자열을 해석하여 데이터를 추출하고, 그 데이터를 변수, 객체, 또는 컬렉션과 같은 프로그래밍 언어의 데이터 구조로 변환하는 과정

- JavaScriptSerializer : .NET에서 JSON 데이터를 처리하고 객체로 직렬화하거나

                                        객체를 JSON 문자열로 역직렬화하는 데 사용됩니다.

 


dynamic dob = js.Deserialize<dynamic>(json);

- JavaScriptSerializer 객체를 사용하여 JSON 문자열을 직렬화하여 C#의 dynamic 타입인 dob 변수에 저장

- JSON 형식의 데이터를 원래의 C# 객체나 데이터 구조로 변환하는 역직렬화 과정을 수행

- JSON 데이터의 구조를 동적으로 처리하기 위함

- Deserialize 메서드를 호출하여 JSON 문자열을 C# 객체로 변환합니다.

* 참고) dynamic은 C# 언어에서 동적 타입(dynamic type)

* 참고) dynamic 형식을 사용한 이유 : JSON 데이터의 구조가 동적이며, JSON의 키-값 쌍의 구성이 고정되어 있지 않아서

 

 

 


dynamic docs = dob["documents"];

- dob 객체에서 "documents" 키에 해당하는 값을 가져와서 dynamic 타입의 docs 변수에 저장

- JSON 데이터의 "documents" 배열을 가져옴

 


object[] buf = docs;

- docs 변수를 object 배열인 buf 변수에 할당

- dynamic 타입의 docs 변수를 object 배열로 형 변환

 


int length = buf.Length;

- buf 배열의 길이를 계산하여 length 변수에 저장

- "documents" 배열의 요소 수를 나타냅니다.

 

 

 

 

 

 

 

 

 

'개발자가 되었다?' 카테고리의 다른 글

Day 19, C# _ Unit Test  (0) 2023.09.11
Day 18, C# (DB 연동_MySQL)  (0) 2023.09.08
Day 16, C#  (0) 2023.09.07
Day 15, C#  (0) 2023.09.05
Day 14, C#  (0) 2023.09.04