What's New

버튼이 있는 말풍선 구현하기

'UIKit framework' 및 Swift 언어를 사용하여 간단한 말풍선을 아래와 같이 구현할 수 있습니다.

  1. 메시지 전송 시, UIView 객체를 생성하기 위해서 'metaData' 프로퍼티에 key-value 데이터를 채워넣습니다.

import UIKit
import TalkPlus

func sendCardViewMessage()  {
 
    guard let channel = <YOUR_TALK_PLUS_CHANNEL> else { return }    
    
    //  fill in the key-value data in 'metaData' property 
    let params = TPMessageSendParams(contentType: .text, 
        messageType: .hidden, 
        channel: channel)
        
    params?.metaData = [
        "type": "msg_with_button",
        "title": "안녕하세요?",
        "body": "버튼이 있는 말풍선입니다.",
        "button_text": "더 자세히 보기",
        "button_action": "SayHello"
    ]
    
     // Send the message to the channel
    TalkPlus.sharedInstance()?.sendMessage(params, success: { message in 
        //  succeeded in sending the message
    }, failure: { errorCode, error in
        // failed in sending message.
    })
}

data의 경우, 최대 10개의 Key-value 형식의 데이터를 넣을 수 있습니다. key, value 둘 다 문자열이어야 합니다. key값의 최대 길이는 128자이고 value값의 최대 길이는 1024자입니다.

  1. 화면에 표시될 데이터를 포함하는 'CardViewMessageModel' 클래스를 정의합니다.

import UIKit

class CardViewMessageModel: Codable {
    var type:String
    var title:String
    var body:String
    var button_text:String
    var button_action:String
    
    init(type: String, 
         title: String,
         body: String,
         button_text: String,
         button_action: String)
    {
        self.type = type
        self.title = title
        self.body = body
        self.button_text = button_text
        self.button_action = button_action
    }
    
    static func addCardView(cvm:CardViewMessage, parentView:UIView) {
        // 1. Container View
        let containerView = UIView()
        containerView.backgroundColor = .white
        containerView.layer.cornerRadius = 10
        containerView.layer.shadowColor = UIColor.black.cgColor
        containerView.layer.shadowOpacity = 0.2
        containerView.layer.shadowOffset = CGSize(width: 0, height: 2)
        containerView.layer.shadowRadius = 4
        containerView.translatesAutoresizingMaskIntoConstraints = false
        parentView.addSubview(containerView)
        // 2. Title Label
        let titleLabel = UILabel()
        titleLabel.text = cvm.title
        titleLabel.font = UIFont.boldSystemFont(ofSize: 18)
        titleLabel.translatesAutoresizingMaskIntoConstraints = false
        containerView.addSubview(titleLabel)
        // 3. Description Label
        let descriptionLabel = UILabel()
        descriptionLabel.text = cvm.body
        descriptionLabel.numberOfLines = 0
        descriptionLabel.font = UIFont.systemFont(ofSize: 14)
        descriptionLabel.translatesAutoresizingMaskIntoConstraints = false
        containerView.addSubview(descriptionLabel)
        // 4. Button
        let button = UIButton(type: .system)
        button.setTitle(cvm.button_text, for: .normal)
        button.backgroundColor = .systemBlue
        button.setTitleColor(.white, for: .normal)
        button.layer.cornerRadius = 5
        button.translatesAutoresizingMaskIntoConstraints = false
        containerView.addSubview(button)
        
        // 5. Auto Layout Constraints
        NSLayoutConstraint.activate([
            // Container View Constraints
            containerView.centerXAnchor.constraint(equalTo: parentView.centerXAnchor),
            containerView.centerYAnchor.constraint(equalTo: parentView.centerYAnchor),
            containerView.widthAnchor.constraint(equalToConstant: 250),
            containerView.heightAnchor.constraint(equalToConstant: 150),
            // Title Label Constraints
            titleLabel.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 16),
            titleLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 16),
            titleLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -16),
            // Description Label Constraints
            descriptionLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 8),
            descriptionLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 16),
            descriptionLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -16),
            // Button Constraints
            button.topAnchor.constraint(equalTo: descriptionLabel.bottomAnchor, constant: 16),
            button.centerXAnchor.constraint(equalTo: containerView.centerXAnchor),
            button.widthAnchor.constraint(equalToConstant: 100),
            button.heightAnchor.constraint(equalToConstant: 40),
            button.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -10)
        ])
    }
}
  1. 'TPChannelDelegate' 프로토콜을 ViewController 객체에 채택하고, 이 프로토콜에 필수적인 메소드를 추가하십시오.

import UIKit
import TalkPlus

class ViewController: UIViewController {
    static func dictionaryToClass<T: Codable>(_ dictionary: [String: Any], 
        type: T.Type) -> T? 
    {
        let decoder = JSONDecoder()
        guard let data = try? JSONSerialization.data(withJSONObject: dictionary, 
            options: .fragmentsAllowed) else { return nil }
        guard let object = try? decoder.decode(T.self, from: data) else {  return nil }
        return object
    }
}

extension ViewController: TPChannelDelegate {

}
  1. 새로운 메시지를 수신받을 때 마다 'messageReceived' 메소드가 호출됩니다. 여기에서 'TPMessage'의 인스턴스 메소드인 'getData' 메소드를 호출하여, Key-Value 데이터를 가져와서 'CardViewMessageModel' 객체를 생성하여 주십시오.

extension ViewController: TPChannelDelegate {
    ... 
    // Called when receiving a new message from the chat channel
    func messageReceived(_ tpChannel: TPChannel!, message tpMessage: TPMessage!) {
        // Create an instance of 'CardViewMessageModel' 
        guard let data = tpMessage.getData() as? [String : Any], 
                    data.count > 0 else { return }
        // Decode key-value data, and then create a new 
        guard let cvm = dictionaryToClass(data, 
            type: CardViewMessageModel.self) else { return }
        // Creates a view and add a view to where you want. 
        CardViewMessageModel.addCardView(cvm: cvm, parentView: self.view)
    }
    ... 
}
  1. 마지막 절차로, 화면 (UIView)를 생성하여 원하는 위치에 추가해야 합니다. 위의 예제 에서는 'CardViewMessageModel.addCardView' 메소드를 호출하여 화면 (UIView) 를 생성하고, 생성된 화면을 부모 뷰에 추가합니다.

Last updated