Conversation
| guard let _ = (scene as? UIWindowScene) else { return } | ||
| guard let windowScene = (scene as? UIWindowScene) else { return } | ||
|
|
||
| // TODO: - rootViewController 설정 |
|
|
||
| import UIKit | ||
|
|
||
| class ViewController: UIViewController { |
There was a problem hiding this comment.
조금 더 구체적인 이름을 지어주는건 어떨까요??
|
|
||
| class ViewController: UIViewController { | ||
|
|
||
| var networkManger = NetworkManger() |
There was a problem hiding this comment.
networkManager를 ViewController에게 주입 시키는 방법은 어떨까요? (init 을 통해서)
이렇게 하는것을 의존성 주입이라고 부르는데, 의존성 주입의 장점에 대해서 알고 계실까요?!
There was a problem hiding this comment.
networkManger 오타가 있는것 같네요ㅎㅎ
|
|
||
| struct ChatRequest: Codable { | ||
| var model: String = "gpt-3.5-turbo-1106" | ||
| var isFalse: Bool = false |
There was a problem hiding this comment.
isFalse 는 뭐가 false 인걸까요??🤔 변수명에 표현이 되면 좋을것 같아요!
| struct ChatResponse: Codable { | ||
| let id: String | ||
| let object: String | ||
| let created: Int |
There was a problem hiding this comment.
createdAt 같은 네이밍은 어떠신가요??ㅎ
| request.allHTTPHeaderFields = header | ||
| request.setValue("application/json", forHTTPHeaderField: "Content-Type") | ||
|
|
||
| let bodyData = ChatRequest(messages: [.init(role: "system", content: "어렵다"),Message(role: "user", content: "swift언어 설명해줘 ")]) |
There was a problem hiding this comment.
지금 리퀘스트 bodyData의 타입을 이렇게 NetworkManager.urlRequest() 메서드 안에서 직접 의존하도록 구현을 하셨는데
이렇게하면 문제점이 뭘까요??🤔
Hint: 다른 API 통신이 추가되는 경우?!
There was a problem hiding this comment.
messages에 들어가는 배열에 첫번째는 .init 으로 생성을하고 두번째는 Message로 직접 생성을 하셨는데 차이를 두신 이유가 있을까요?!
| var OPENAI_API_KEY: String { | ||
| guard let file = self.path(forResource: "Api_Key", ofType: "plist") else { return "" } | ||
|
|
||
| // .plist를 딕셔너리로 받아오기 | ||
| guard let resource = NSDictionary(contentsOfFile: file) else { return "" } | ||
|
|
||
| // 딕셔너리에서 값 찾기 | ||
| guard let key = resource["myApiKey"] as? String else { | ||
| fatalError("API_KEY error") | ||
| } | ||
| return key | ||
| } |
There was a problem hiding this comment.
오 API Key 를 숨기는 고민을 이렇게 하신거군요?! 저는 이런거 고민 사실 제대로 안해본거 같은데 아주 멋집니다!
추가로 고민하신 방법도 있을까요?? (개인적으로 궁금해서요!)
There was a problem hiding this comment.
개인적인 생각으로는, 진짜 숨겨야하는 API Key가 있다면
이건 결국 서버에 도움이 필요하지 않을까 싶네요..?🤔 물론 다른 방법도 있을 수는 있겠지만
가장 안전한 방법은 서버로부터 (당연히 지금 사용하는 API 를 제공하는 서버 외의 다른 서버 겠죠 ?ㅎㅎ)
API Key를 제공 받아서, Keychain에 저장하는게 안전하지 않을까 싶습니다..! (개인적인 생각)
|
|
||
| import Foundation | ||
|
|
||
| extension Bundle { |
There was a problem hiding this comment.
이게 Bundle 익스텐션으로 들어가게 된 이유가 있나요? (그냥 개인적으로 궁금해서요! )
| networkManger.urlDataTaks { result in | ||
| switch result { | ||
| case .success(let data): | ||
| let decodedResult: Result<ChatResponse, NetworkError> = self.networkManger.DecodedData(data: data) | ||
| switch decodedResult { |
There was a problem hiding this comment.
요거 코멘트로 질문 주신 내용 같네요!
switch 문을 중첩으로 안하는 방법을 여쭤보신것 같은데
지금 urlDataTaks (오타가 있는것 같네요 ! ㅎㅎ) 의 completion으로 Result 타입을 받아서, success 일때 또 self.networkManager.decodedData()를 호출하고 있네요!
개인적으로 요런 방법들이 생각나네요!
- 그냥 두개의 메서드를 networkManager에서 다 알아서 decoding 까지 해서 ViewController에게 결과를 전달한다.
- decoding 하는 부분은 별도의 메서드로 분리한다.
| request.httpBody = body | ||
|
|
||
| return request | ||
|
|
There was a problem hiding this comment.
리턴 다음에 줄바꿈 추가하는건 컨벤션일까요? 아니라면 제거하면 좋을것 같아요!
리뷰어:
@junbangg
버드:
@ujhong7
@ianK0909
안녕하세요! AI 챗봇 앱 프로젝트를 함께하게된 홍, 이안입니다.
잘부탁드립니다😊
구현한 코드
Open API 사용하기 위해 필요한 요청 객체, 응답 데이터 타입을 구현하고 네트워킹 요청을 하기위해 URLSession을 이용하여 메시지를 전송하고 , 응답처리를 구현 하였습니다.
API Key가 공개되어있어서 숨기는것도 구현해봤습니다.
구현하면서 궁금한점