네 접니다.
지난 게시물에 이어서 이번에는 실질적 채팅 기능을 구현하는 방법에 대해 작성하겠습니다.
https://pinlib.tistory.com/entry/SWIFT-IOS에서-채팅기능-구현하기2-with-AWS-Amplify
이전 게시물을 읽어보시고 이번 게시물을 읽어보시는 것을 추천드립니다.
이번이 message구현의 마지막 게시물이자 해당 project자체도 마지막 게시물이 될 것 같네요.
이 글이 올라가는 기점으로 제가 aws를 해지할 생각이라서...,
뭐 어쨋든 잡설은 치우고 이어서 글을 작성해볼게여
0. 변수 선언
각각의 함수를 구현하기에 앞서, 해당 함수를 사용하기 위해서는 아래의 변수들을 선언해야 합니다.
class ChattingViewController: MessagesViewController {
var otherPerson: String?
var currentUser = Sender(senderId: "self", displayName: "current user")
var otherUser = Sender(senderId: "other", displayName: "other user")
var messages = [MessageType]()
var unique_channel : String!
var detailData = [String:String]()
var subscription: AmplifyAsyncThrowingSequence<GraphQLSubscriptionEvent<ChatMessage>>?
1. InputBarAccessoryViewDelegate
extension ChattingViewController: InputBarAccessoryViewDelegate {
func inputBar(_ inputBar: InputBarAccessoryView, didPressSendButtonWith text: String) {
// Create a new ChatMessage
let email = userGetAuth()
Task{
if(otherPerson != nil){
//comment로 들어옴
let member_channels = try await Amplify.DataStore.query(ChatChannel.self, where: ChatChannel.keys.Member1.eq(email) && ChatChannel.keys.Member2.eq(otherPerson))
for member_channel in member_channels {
unique_channel = member_channel.id
}
if(unique_channel != nil){
//채팅방 존재의 경우 -> 현재 channel값 이용
await saveMessage(unique_channel,email!,text, .normal)
} else {
await addChatRoom(email!, otherPerson!, "dateString", .normal)
let member_channel2s = try await Amplify.DataStore.query(ChatChannel.self, where: ChatChannel.keys.Member1.eq(email) && ChatChannel.keys.Member2.eq(otherPerson))
for member_channel2 in member_channel2s {
unique_channel = member_channel2.id
}
await saveMessage(unique_channel,email!,text, .normal)
}
} else {
//list view로 들어옴
unique_channel = detailData["channel"]
await saveMessage(unique_channel,email!,text, .normal)
}
}
inputBar.inputTextView.text.removeAll()
}
}
우선 이전에 소개한 userGetAuth함수로 유저의 이메일 정보를 받아옵니다.
이후, 가져온 email을 이용해 채팅방의 존재 여부(입장경로)를 파악한 후 input_bar에 들어간 text내용을
saveMessage의 parameter로 사용합니다.
여기서 입장경로란
최초로 채팅을 하게 될 경우에는 채널(채팅방)이 따로 생성되어 있지 않으므로 addChatRoom함수를 이용해 채널을 신규 생성해줘야 합니다.
허나, 이미 채널이 존재하면 saveMessage함수를 바로 호출하기만 하면 됩니다.
2. saveMessage
private func saveMessage(_ channel: String, _ sender: String, _ message: String, _ priority: Priority) async {
do {
let currentDate = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM-dd HH:mm"
let dateString = dateFormatter.string(from: currentDate)
let item = ChatMessage(id: UUID().uuidString, channel: channel, sender: sender, message: message, timestamp: dateString, priority: priority)
_ = try await Amplify.DataStore.save(item)
} catch {
print("Could not save item to dataStore: \(error)")
}
}
InputBarAccessoryViewDelegate함수에서 parameter로 넘어온 값을 이전에 만든 ChatMessage struct에 담아
AWS Amplify 서버에 메시지를 저장해줍니다.
3. addChatRoom
private func addChatRoom(_ member1: String, _ member2: String, _ dateString: String,_ priority: Priority) async {
do{
let userEmail = userGetAuth()
let item = ChatChannel(id: UUID().uuidString, Member1: userEmail!, Member2: member2, Date: dateString, priority: priority)
_ = try await Amplify.DataStore.save(item)
print(dateString)
} catch {
print("Could not save item to dataStore: \(error)")
}
}
}
해당 함수의 경우, InputBarAccessoryViewDelegate에서 채널이 없을 경우 호출하게 되며
새롭게 채널(채팅방)을 생성하게 됩니다.
4. readMessage
private func readMessage(_ noticeNumber: String) async {
do {
let email = userGetAuth()
currentUser.senderId = email!
let myinfos = try await Amplify.DataStore.query(User.self, where: User.keys.id.eq(email))
for myinfo in myinfos {
currentUser.displayName = myinfo.UserNickName
}
if(detailData["member2"] != nil){
otherUser.senderId = detailData["member2"]!
let yourinfos = try await Amplify.DataStore.query(User.self, where: User.keys.id.eq(detailData["member2"]))
for yourinfo in yourinfos {
otherUser.displayName = yourinfo.UserNickName
}
}
if(otherPerson != nil){
//comment로 들어옴
otherUser.senderId = otherPerson!
let yourinfos = try await Amplify.DataStore.query(User.self, where: User.keys.id.eq(otherPerson))
for yourinfo in yourinfos {
otherUser.displayName = yourinfo.UserNickName
}
}
let awsMessages = try await Amplify.DataStore.query(ChatMessage.self, where: ChatMessage.keys.channel.eq(unique_channel))
for awsMessage in awsMessages {
if(awsMessage.sender == email){
//내꺼
messages.append(Message(sender: currentUser,
messageId: awsMessage.id,
sentDate: Date().addingTimeInterval(-86400),
kind: .text(awsMessage.message),
channel: awsMessage.channel))
} else {
//니꺼
messages.append(Message(sender: otherUser,
messageId: awsMessage.id,
sentDate: Date().addingTimeInterval(-86400),
kind: .text(awsMessage.message),
channel: awsMessage.channel))
}
}
} catch {
print("Could not query DataStore: \(error)")
}
}
AWS Amplify에 저장된 메시지(데이터)를 채팅창으로 불러오는 함수입니다.
여기서는 이전에 만든 message struct를 이용합니다.
5. AWS Amplify Real-time
이제 AWS Amplifty의 Real-time을 구현해야 합니다.
메시지를 전송하고 받을 때 마다, 서버로 부터 데이터를 받아오는 즉, 갱신과정의 코드입니다.
아래는 subscription 함수입니다.
func createSubscription() async{
if let subscription = subscription {
Task {
do {
for try await subscriptionEvent in subscription {
switch subscriptionEvent {
case .connection(let subscriptionConnectionState):
print("Subscription connect state is \(subscriptionConnectionState)")
case .data(let result):
switch result {
case .success(let createdTodo):
print("Successfully got todo from subscription: \(createdTodo)")
case .failure(let error):
print("Got failed result with \(error.errorDescription)")
}
}
}
} catch {
print("Subscription has terminated with \(error)")
}
}
} else {
print("Subscription is nil")
}
}
//real-time unsubscribtion
func cancelSubscription() {
// Cancel the subscription listener when you're finished with it
subscription?.cancel()
}
이렇게 저의 Luvky 프로젝트의 장례식이 마무리 되었습니다.
사실 더 많은 코드들을 소개 할 계획이었는데,
이제는 꼴도 보기 싫어서 좀 빠르게 마무리한 감이 있네요.
요즘 생각이 좀 많았습니다.
근본적으로 해야 할 일들이 생기다 보니,
셀프 가스라이팅에 걸려서 하고 싶은 일도 바뀌고
다른 공부를 해야되더라구요
글의 주제가 이제 또 바뀔 수도 있습니다.
그래도 어차피 맥북도 있으니깐 소규모 프로젝트로 해보고 싶은거 앱형식으로 간단히 만들 꺼 같기는 합니다.
다음 게시물은 제 추측으로는 첫 해외 여행인 홍콩여행이 될 거 같습니다.
사실 갔다온지 좀 되긴 했는데...,
모르겠습니다.
하고 싶은 일이 바꼈는데
공부는 못하고 있고, 그냥 처리해야 될 이상한 일들만 생긴다.
잘 모르겠다
담배나 삐리삐리빠라뽕하러 갈게염
수고염
'ios 앱개발' 카테고리의 다른 글
[SWIFT] IOS에서 채팅기능 구현하기(2) with AWS Amplify (0) | 2024.02.18 |
---|---|
[SWIFT] IOS에서 채팅기능 구현하기(1) with AWS Amplify (0) | 2024.02.16 |
[SWIFT] IOS에서 카카오 로그인 구현하기 with AWS Amplify (0) | 2024.02.11 |
[SWIFT] IOS에서 AWS Amplify를 이용해 이미지 저장과 불러오기(S3 storage) (0) | 2024.02.10 |
[SWIFT] IOS 에서 AWS Amplify를 이용해 CRUD 구현하기 (1) | 2024.02.08 |