ユーザーがAWS Lexチャットボットと通信できるようにするアプリケーションを構築していますが、今のところ問題はボタンをタップしてボットと会話を開始するときですクラッシュや私にスレッド1与えます:この行のEXC_BAD_INSTRUCTIONエラー:AWSスワイプクラスの設定行でスレッド1が発生する:EXC_BAD_INSTRUCTION
let configuration = AWSServiceConfiguration(region: botRegion!, credentialsProvider: AWSIdentityManager.default().credentialsProvider)
のXcodeは、任意の重要な部分を強調しないように私は本当に、それはこのように動作するように引き起こしているものを知っていただきたいと思いますコード。
以下は、私のコードが興味のある人のために全体的にどのように見えるかです。
import Foundation
import UIKit
import Photos
import JSQMessagesViewController
import AWSLex
import AWSMobileHubHelper
let ClientSenderId = "Client"
let ServerSenderId = "Server"
class JeevesChatViewController: JSQMessagesViewController, JSQMessagesComposerTextViewPasteDelegate {
// The name of the bot.
var botName: String?
// The bot region
var botRegion: AWSRegionType?
// The bot alias
var botAlias: String?
// The messages communicated between the client and the server
var messages: [JSQMessage]?
// The interaction kit client
var interactionKit: AWSLexInteractionKit?
// The session attributes
var sessionAttributes: [AnyHashable: Any]?
// Contents of outgoing image
var outgoingBubbleImageData: JSQMessagesBubbleImage?
// Contents of incoming image
var incomingBubbleImageData: JSQMessagesBubbleImage?
// Used to store task completion source of iteraction kit
var textModeSwitchingCompletion: AWSTaskCompletionSource<NSString>?
// The client image
var clientImage: JSQMessagesAvatarImage?
// The bot image
var serverImage: JSQMessagesAvatarImage?
override func viewDidLoad() {
super.viewDidLoad()
// Make the initial setup for the bot.
// Error occurs here - fatal error: unexpectedly found nil while unwrapping an Optional value
let configuration = AWSServiceConfiguration(region: botRegion!, credentialsProvider: AWSIdentityManager.default().credentialsProvider)
// Setup interaction kit configuration
let botConfig = AWSLexInteractionKitConfig.defaultInteractionKitConfig(withBotName:botName!, botAlias: botAlias!)
// Disable automatic voice playback
botConfig.autoPlayback = false
// Register the interaction kit client
AWSLexInteractionKit.register(with: configuration!, interactionKitConfiguration: botConfig, forKey: botName!)
// Fetch and set the interaction kit client
self.interactionKit = AWSLexInteractionKit.init(forKey: botName!)
// Set the interaction kit delegate
// Remove 'as? AWSLexInteractionDelegate' statement later
self.interactionKit?.interactionDelegate = self
// Setup JSQMessagesViewController configuration
self.showLoadEarlierMessagesHeader = false
// Initialise the avatars for client and server here.
// Setup the default keyboard type.
self.inputToolbar.contentView?.textView?.keyboardType = UIKeyboardType.default
// Initialise the messages list
self.messages = [JSQMessage]()
// Set the colours for messages bubbles
let bubbleFactory = JSQMessagesBubbleImageFactory()
self.outgoingBubbleImageData = bubbleFactory?.outgoingMessagesBubbleImage(with: UIColor.jsq_messageBubbleGreen())
self.incomingBubbleImageData = bubbleFactory?.incomingMessagesBubbleImage(with: UIColor.jsq_messageBubbleBlue())
self.inputToolbar.contentView?.leftBarButtonItem = nil
self.senderDisplayName = "User"
self.senderId = ClientSenderId
}
// MARK: - JSQMessagesViewController delegate methods
override func didPressSend(_ button: UIButton!, withMessageText text: String!, senderId: String!, senderDisplayName: String!, date: Date!) {
let message = JSQMessage(senderId: senderId, senderDisplayName: senderDisplayName, date: date, text: text)
self.messages?.append(message!)
if let textModeSwitchingCompletion = textModeSwitchingCompletion {
textModeSwitchingCompletion.set(result: text as NSString)
self.textModeSwitchingCompletion = nil
}
else {
self.interactionKit?.text(inTextOut: text)
}
self.finishSendingMessage(animated: true)
}
override func collectionView(_ collectionView: JSQMessagesCollectionView, messageDataForItemAt indexPath: IndexPath) -> JSQMessageData {
return self.messages![indexPath.item]
}
override func collectionView(_ collectionView: JSQMessagesCollectionView, didDeleteMessageAt indexPath: IndexPath) {
// Nothing happens here
}
override func collectionView(_ collectionView: JSQMessagesCollectionView, messageBubbleImageDataForItemAt indexPath: IndexPath) -> JSQMessageBubbleImageDataSource {
let message = self.messages![indexPath.item]
if (message.senderId == self.senderId) {
return self.outgoingBubbleImageData!
}
return self.incomingBubbleImageData!
}
override func collectionView(_ collectionView: JSQMessagesCollectionView, avatarImageDataForItemAt indexPath: IndexPath) -> JSQMessageAvatarImageDataSource? {
let message = messages![indexPath.item]
if message.senderId == ClientSenderId {
return self.clientImage
}
return self.serverImage
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if let messages = messages {
return messages.count
}
return 0
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = (super.collectionView(collectionView, cellForItemAt: indexPath) as! JSQMessagesCollectionViewCell)
let msg = self.messages?[indexPath.item]
if !msg!.isMediaMessage {
if (msg?.senderId == self.senderId) {
cell.textView?.textColor = UIColor.black
}
else {
cell.textView?.textColor = UIColor.white
}
}
return cell
}
override func collectionView(_ collectionView: JSQMessagesCollectionView, attributedTextForCellTopLabelAt indexPath: IndexPath) -> NSAttributedString? {
if indexPath.item % 3 == 0 {
let message = self.messages?[indexPath.item]
return JSQMessagesTimestampFormatter.shared().attributedTimestamp(for: message!.date)
}
return nil
}
override func collectionView(_ collectionView: JSQMessagesCollectionView, attributedTextForMessageBubbleTopLabelAt indexPath: IndexPath) -> NSAttributedString? {
let message = self.messages?[indexPath.item]
// iOS 7 sender name labels
if (message?.senderId == self.senderId) {
return nil
}
if indexPath.item - 1 > 0 {
let previousMessage = self.messages?[indexPath.item - 1]
if (previousMessage?.senderId == message?.senderId) {
return nil
}
}
// Do not specify attributes to use the default values.
return NSAttributedString(string: message!.senderDisplayName)
}
override func collectionView(_ collectionView: JSQMessagesCollectionView, attributedTextForCellBottomLabelAt indexPath: IndexPath) -> NSAttributedString? {
return nil
}
func composerTextView(_ textView: JSQMessagesComposerTextView, shouldPasteWithSender sender: Any) -> Bool {
return true
}
}
// MARK: - Bot Interaction Kit
extension JeevesChatViewController: AWSLexInteractionDelegate {
func interactionKit(_ interactionKit: AWSLexInteractionKit, onError error: Error) {
print("Error occurred: \(error)")
}
func interactionKit(_ interactionKit: AWSLexInteractionKit, switchModeInput: AWSLexSwitchModeInput, completionSource: AWSTaskCompletionSource<AWSLexSwitchModeResponse>?) {
self.sessionAttributes = switchModeInput.sessionAttributes
DispatchQueue.main.async(execute: {
let message: JSQMessage
// Handle a successful transaction
if (switchModeInput.dialogState == AWSLexDialogState.readyForFulfillment) {
// Currently just displaying the slots return on ready for fulfillment
if let slots = switchModeInput.slots {
message = JSQMessage(senderId: ServerSenderId, senderDisplayName: "", date: Date(), text: "Slots:\n\(slots)")
self.messages?.append(message)
self.finishSendingMessage(animated: true)
}
} else {
message = JSQMessage(senderId: ServerSenderId, senderDisplayName: "", date: Date(), text: switchModeInput.outputText!)
self.messages?.append(message)
self.finishSendingMessage(animated: true)
}
})
// This can be expanded to take input from the user.
let switchModeResponse = AWSLexSwitchModeResponse()
switchModeResponse.interactionMode = AWSLexInteractionMode.text
switchModeResponse.sessionAttributes = switchModeInput.sessionAttributes
completionSource?.set(result: switchModeResponse)
}
func interactionKitContinue(withText interactionKit: AWSLexInteractionKit, completionSource: AWSTaskCompletionSource<NSString>) {
textModeSwitchingCompletion = completionSource
}
}
サンプルをダウンロードして、同じコード行を使用して比較したそれは私のプロジェクトではなく、そこで動作しますか? –
サンプルプロジェクトのAppDelegateファイルをチェックインし、そこに初期化されているかどうかを教えてください – mnabaa