애니메이션이 작동을 안 했습니다. 구글과 관련된 아이콘, 애니메이션을 쓸려면 추가해야 되는지 처음 알게 되었다.
역시 이래서 기초가 매우 매우 중요한 거 같다.
또한 실시간 검색이 생각보다 API 호출량이 매우 번번하게 발생한다는 사실과
이해 해당하는 방법이 있다는 사실을 처음 알았습니다.
원래는 검색버튼을 눌러서 결과를 찾는 건 만들어 봤어도
실시간으로 바로 뜨는 건 안 만들어봤었는데 새로운 경험이었다.
실시간 검색 만들기
먼저 함수를 설명해 주면
앞에 6번, 7번에서 가져왔던 네이버 지역 검색 API를 기점으로 만들었습니다.
bool _isLoading = false; // 로딩 상태를 나타내는 변수
String _responseBody = "검색 결과가 여기에 표시됩니다."; // API 응답을 저장할 변수
final TextEditingController _searchController = TextEditingController(); // 검색어 입력을 위한 컨트롤러
Timer? _debounce; // 입력 지연을 위한 타이머
static const int _minSearchLength = 2; // 최소 검색어 길이
static const Duration _debounceDuration = Duration(milliseconds: 500); // 입력 지연 시간
사실 AI로 그냥 실시간 검색을 뽑아서 만들긴 했는데
실시간 검색은 한모음자음 당 API호출을 한 번씩 했다.
매우 많이 API 호출이 발생하기 때문에
500ms(0.5)라는 시간 텀을 두고 불러오게 만들었습니다
또한 최소 검색어 길이가 2글자 ( 지역은 한 글자가 없기 때문에) 에만 api가 호출되게 만들었습니다.
앞서 검색 테스트를 할 때 썼던 코드만 가져와서
도로명 주소만 뜨게 하였습니다.
Future<void> _fetchData(String query) async {
if (query.length < _minSearchLength) return; // 최소 검색어 길이 미달 시 종료
setState(() {
_isLoading = true; // 로딩 시작
});
final String clientId = '1'; // 네이버 개발자 센터에서 발급받은 Client ID
final String clientSecret = '1'; // 네이버 개발자 센터에서 발급받은 Client Secret
final String url =
'1'; // API 요청 URL
try {
// HTTP GET 요청
final response = await http.get(
Uri.parse(url),
headers: {
'X-Naver-Client-Id': clientId,
'X-Naver-Client-Secret': clientSecret,
},
);
if (response.statusCode == 200) {
// 성공적으로 응답을 받았을 경우
final Map<String, dynamic> data = json.decode(response.body); // JSON 응답 파싱
final List<dynamic> items = data['items']; // 검색 결과 아이템 목록
setState(() {
// UI 업데이트
_responseBody = items.map((item) {
final title = item['title']; // 제목
final document = html_parser.parse(title); // HTML 파싱
final cleanTitle = document.body?.text ?? ''; // HTML 태그 제거
final roadAddress = item['roadAddress'] ?? '도로명 주소 없음'; // 도로명 주소
final address = item['address'] ?? '지번 주소 없음'; // 지번 주소
final latitude = item['mapy']; // 위도
final longitude = item['mapx']; // 경도
final parsedLatitude = _parseCoordinate(latitude, isLatitude: true); // 위도 변환
final parsedLongitude = _parseCoordinate(longitude, isLatitude: false); // 경도 변환
// 결과 문자열 생성
return '$cleanTitle';
//return '$cleanTitle\n도로명: $roadAddress\n지번: $address\n위도: $parsedLatitude, 경도: $parsedLongitude\n';
}).join('\n');
});
} else {
// 응답 실패 시
setState(() {
_responseBody = 'Failed to load data: ${response.statusCode}';
});
}
} catch (e) {
// 예외 발생 시
setState(() {
_responseBody = 'Error: $e';
});
} finally {
setState(() {
_isLoading = false; // 로딩 종료
});
}
}