Sinch framework (Objective C) and Swift not compatible - ios

I am using Sinch SDK (link) which is written in Objective C.
But I am making a Swift application. I created bridge header and I added some basic functionality in the view controller:
import UIKit
class ViewController: UIViewController, SINMessageClientDelegate {
override func viewDidLoad() {
super.viewDidLoad()
initializeSinch()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func initializeSinch()
{
// Instantiate a Sinch client object
let sinchClient = Sinch.clientWithApplicationKey("xxxxxxxxxxxx", applicationSecret: "xxxxxxxxxx", environmentHost: "sandbox.sinch.com", userId: "user1")
sinchClient.setSupportMessaging(true)
sinchClient.start()
let messageClient = sinchClient.messageClient()
let message = SINOutgoingMessage(recipient: "user2", text: "Test 123, test 123")
messageClient.sendMessage(message)
}
// Tells the delegate that a message has been received.
func messageClient(messageClient: SINMessageClient, didReceiveIncomingMessage message: SINMessage) {
// Present a Local Notification if app is in background
if UIApplication.sharedApplication().applicationState == .Background {
var notification: UILocalNotification = UILocalNotification()
notification.alertBody = "Message from \(message.recipientIds[0])"
UIApplication.sharedApplication().presentLocalNotificationNow(notification)
}
else {
// Update UI in-app
}
}
// Tells the delegate that a message for a specific recipient has been sent by the local user.
func messageSent(message: SINMessage, recipientId: String) {
// var a = 1
}
//
// Tells the delegate that a message has been delivered (to a particular recipient).
func messageDelivered(info: SINMessageDeliveryInfo) {
// var a = 1
}
func messageFailed(message: SINMessage, info messageFailureInfo: SINMessageFailureInfo) {
// var a = 1
}
}
This is how the error looks like.
Can someone advice how can I fix this?

Have you added all the neccesary frameworks, and the linker flags?
AudioToolbox.framework
AVFoundation.framework
Security.framework
Some additional linker flags need to be added. In the Build Settings pane for the application target, set the following:
Other Linker Flags -> -ObjC -Xlinker -lc++
https://www.sinch.com/docs/voice/ios/

Related

How can we detect if user press the "Send/Return" button on keyboard with MessageKit?

I would like the user to be able to send messages when he/she presses the "Send" button on the keyboard also. For a textField I know that can be achieved with the delagte. But could anyone please point me how can we do this in MessageKit? I was not able to find a proper method to use here.
Thanks in advance!
A detailed explanation can be found in the example project on the MessageKit repo.
The code snippet for implemeting sending the message on a Send button tap, can be seen below:
import UIKit
import MessageKit
import InputBarAccessoryView
class MyViewController: MessagesViewController {
override func viewDidLoad() {
super.viewDidLoad()
messageInputBar.delegate = self //set the delegate to receive notifications from the `InputBarAccessoryView`
}
}
extension MyViewController: InputBarAccessoryViewDelegate {
#objc internal func inputBar(_ inputBar: InputBarAccessoryView, didPressSendButtonWith text: String) {
processInputBar(messageInputBar)
}
private func processInputBar(_ inputBar: InputBarAccessoryView) {
let components = inputBar.inputTextView.components
inputBar.inputTextView.text = String()
inputBar.invalidatePlugins()
inputBar.inputTextView.resignFirstResponder() // Resign first responder for iPad split view
DispatchQueue.global(qos: .default).async {
DispatchQueue.main.async { [weak self] in
guard let self = self else {return}
self.insertMessages(components)
self.messagesCollectionView.scrollToLastItem(animated: true)
}
}
}
private func insertMessages(_ data: [Any]) {
for component in data {
if let string = component as? String {
// Create a Message type and add it the the chat messages
// let message = Message(sender: currentUser, messageId: UUID().uuidString, kind: .text(string))
}
else if let image = component as? UIImage {
let item = ImageMediaItem(image: image)
// Create a Message type and add it the the chat messages
// let message = Message(sender: currentUser, messageId: UUID().uuidString, kind: .photo(item))
}
}
}
}

Embed Unity inside iOS in own ViewController

Using Unity 2019.3.0f3 and its Unity as a library feature I'm trying to embed a Unity project inside my iOS application.
Unity officially only supports full screen rendering. Nevertheless I'm looking for a way around that restriction.
In previous versions of Unity i successfully used swift-unity to do the integration. Within this approach it is easy to just get the View where Unity is rendering to (using UnityGetGLView()). I had no problems regarding stability or resources.
Using the new library approach, every time I try to access the UnityView, unity forces it's complete Window as keyWindow.
I tried accessing the UnityView in my own ViewController using
if let unityView = UnityFramework.getInstance()?.appController()?.rootViewController.view {
// insert subview at index 0 ensures unity view is behind current UI view
view?.insertSubview(unityView, at: 0)
}
But that immediately activates the complete unity-window and hides my parenting UITabBarController.
Trying to make the UnityFramework.getInstance()?.appController()?.rootViewController a child of my UITabBarController failed with the same result.
Furthermore it is not possible to add a child ViewController. Only adding subviews seems possible.
Does anybody know where that window-behaviour is located or how i can access the UnityView (or the RootViewController) and use it freely?
I found a solution to the problem based on this approach from the unity forum. Using this approach I'm able to use the UnityViewController as a child in my own TabBarController.
The approach is working for Unity 2019.3.0f3, but I'm not sure if it will work in future versions. It feels like Unity tries to actively prevent such use. Then again I found hints in comments in the library-code that would suggest that a modified ViewController-Hierarchy was at least contemplated e.g. in UnityAppController+ViewHandling.h. But the instructions are unclear and methods with the hinted names don't exist.
Solution
1. Create UnityEmbeddedSwift.swift
The official example App provided by Unity is a real mess. I ended up using the UnityEmbeddedSwift.swift from the linked forum post with additions for pausing. This class encapsulates all Unity-related functionality in one clean class.
//
// UnityEmbeddedSwift.swift
// Native
//
// Created by NSWell on 2019/12/19.
// Copyright © 2019 WEACW. All rights reserved.
//
//
// Created by Simon Tysland on 19/08/2019.
// Copyright © 2019 Simon Tysland. All rights reserved.
//
import Foundation
import UnityFramework
class UnityEmbeddedSwift: UIResponder, UIApplicationDelegate, UnityFrameworkListener {
private struct UnityMessage {
let objectName : String?
let methodName : String?
let messageBody : String?
}
private static var instance : UnityEmbeddedSwift!
private var ufw : UnityFramework!
private static var hostMainWindow : UIWindow! // Window to return to when exiting Unity window
private static var launchOpts : [UIApplication.LaunchOptionsKey: Any]?
private static var cachedMessages = [UnityMessage]()
// MARK: - Static functions (that can be called from other scripts)
static func getUnityRootViewController() -> UIViewController! {
return instance.ufw.appController()?.rootViewController
}
static func getUnityView() -> UIView! {
return instance.ufw.appController()?.rootViewController?.view
}
static func setHostMainWindow(_ hostMainWindow : UIWindow?) {
UnityEmbeddedSwift.hostMainWindow = hostMainWindow
let value = UIInterfaceOrientation.landscapeLeft.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
}
static func setLaunchinOptions(_ launchingOptions : [UIApplication.LaunchOptionsKey: Any]?) {
UnityEmbeddedSwift.launchOpts = launchingOptions
}
static func showUnity() {
if(UnityEmbeddedSwift.instance == nil || UnityEmbeddedSwift.instance.unityIsInitialized() == false) {
UnityEmbeddedSwift().initUnityWindow()
}
else {
UnityEmbeddedSwift.instance.showUnityWindow()
}
}
static func hideUnity() {
UnityEmbeddedSwift.instance?.hideUnityWindow()
}
static func pauseUnity() {
UnityEmbeddedSwift.instance?.pauseUnityWindow()
}
static func unpauseUnity() {
UnityEmbeddedSwift.instance?.unpauseUnityWindow()
}
static func unloadUnity() {
UnityEmbeddedSwift.instance?.unloadUnityWindow()
}
static func sendUnityMessage(_ objectName : String, methodName : String, message : String) {
let msg : UnityMessage = UnityMessage(objectName: objectName, methodName: methodName, messageBody: message)
// Send the message right away if Unity is initialized, else cache it
if(UnityEmbeddedSwift.instance != nil && UnityEmbeddedSwift.instance.unityIsInitialized()) {
UnityEmbeddedSwift.instance.ufw.sendMessageToGO(withName: msg.objectName, functionName: msg.methodName, message: msg.messageBody)
}
else {
UnityEmbeddedSwift.cachedMessages.append(msg)
}
}
// MARK - Callback from UnityFrameworkListener
func unityDidUnload(_ notification: Notification!) {
ufw.unregisterFrameworkListener(self)
ufw = nil
UnityEmbeddedSwift.hostMainWindow?.makeKeyAndVisible()
}
// MARK: - Private functions (called within the class)
private func unityIsInitialized() -> Bool {
return ufw != nil && (ufw.appController() != nil)
}
private func initUnityWindow() {
if unityIsInitialized() {
showUnityWindow()
return
}
ufw = UnityFrameworkLoad()!
ufw.setDataBundleId("com.unity3d.framework")
ufw.register(self)
// NSClassFromString("FrameworkLibAPI")?.registerAPIforNativeCalls(self)
ufw.runEmbedded(withArgc: CommandLine.argc, argv: CommandLine.unsafeArgv, appLaunchOpts: UnityEmbeddedSwift.launchOpts)
sendUnityMessageToGameObject()
UnityEmbeddedSwift.instance = self
}
private func showUnityWindow() {
if unityIsInitialized() {
ufw.showUnityWindow()
sendUnityMessageToGameObject()
}
}
private func hideUnityWindow() {
if(UnityEmbeddedSwift.hostMainWindow == nil) {
print("WARNING: hostMainWindow is nil! Cannot switch from Unity window to previous window")
}
else {
UnityEmbeddedSwift.hostMainWindow?.makeKeyAndVisible()
}
}
private func pauseUnityWindow() {
ufw.pause(true)
}
private func unpauseUnityWindow() {
ufw.pause(false)
}
private func unloadUnityWindow() {
if unityIsInitialized() {
UnityEmbeddedSwift.cachedMessages.removeAll()
ufw.unloadApplication()
}
}
private func sendUnityMessageToGameObject() {
if (UnityEmbeddedSwift.cachedMessages.count >= 0 && unityIsInitialized())
{
for msg in UnityEmbeddedSwift.cachedMessages {
ufw.sendMessageToGO(withName: msg.objectName, functionName: msg.methodName, message: msg.messageBody)
}
UnityEmbeddedSwift.cachedMessages.removeAll()
}
}
private func UnityFrameworkLoad() -> UnityFramework? {
let bundlePath: String = Bundle.main.bundlePath + "/Frameworks/UnityFramework.framework"
let bundle = Bundle(path: bundlePath )
if bundle?.isLoaded == false {
bundle?.load()
}
let ufw = bundle?.principalClass?.getInstance()
if ufw?.appController() == nil {
// unity is not initialized
// ufw?.executeHeader = &mh_execute_header
let machineHeader = UnsafeMutablePointer<MachHeader>.allocate(capacity: 1)
machineHeader.pointee = _mh_execute_header
ufw!.setExecuteHeader(machineHeader)
}
return ufw
}
}
2. Modify AppDelegate.swift
Sets window and launch options needed by UnityEmbeddedSwift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
UnityEmbeddedSwift.setHostMainWindow(window)
UnityEmbeddedSwift.setLaunchinOptions(launchOptions)
return true
}
3. Create RootTabBarController.swift
This class sets up the hierarchy.
It is important to use the UnityRootViewController right after calling UnityEmbeddedSwift.showUnity().
The Tab-Switching is not nice, but if it is missing Unity will pause (or freeze?) during loading. The timing seems to depend on the Unity-Projects loading time. It can be faster for small projects and needs more time for larger projects.
import UIKit
class RootTabBarController: UITabBarController, UITabBarControllerDelegate {
var unityNC: UINavigationController?
var nativeNC: UINavigationController?
override func viewDidLoad() {
super.viewDidLoad()
delegate = self
// start unity and immediatly set as rootViewController
// this loophole makes it possible to run unity in the same window
UnityEmbeddedSwift.showUnity()
let unityViewController = UnityEmbeddedSwift.getUnityRootViewController()!
unityViewController.navigationItem.title = "Unity"
unityNC = UINavigationController.init(rootViewController: unityViewController)
unityNC?.tabBarItem.title = "Unity"
let nativeViewController = UIViewController.init()
nativeViewController.view.backgroundColor = UIColor.darkGray
nativeViewController.navigationItem.title = "Native"
nativeNC = UINavigationController.init(rootViewController: nativeViewController)
nativeNC?.tabBarItem.title = "Native"
viewControllers = [unityNC!, nativeNC!]
// select other tab and reselect first tab to unfreeze unity-loading
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2, execute: {
self.selectedIndex = 1
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01, execute: {
self.selectedIndex = 0
})
})
}
// MARK: - UITabBarControllerDelegate
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
// pause unity if unity-tab is not selected
if viewController != unityNC {
UnityEmbeddedSwift.pauseUnity()
} else {
UnityEmbeddedSwift.unpauseUnity()
}
}
}
4. Modify Main.storyboard
Modify the storyboard to start with the RootTabBarController.
For anyone who is still interested in preventing the freezing, I am building on top of aalmigthy's answer:
You do not need to add a TabBar controller and switch between the tabs. All you need to do is:
Add the Unity view as a subview
Send the subview to back
Here's the modified ViewController class (no need for a tab bar):
import UIKit
class HybridViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
UnityEmbeddedSwift.showUnity()
let uView = UnityEmbeddedSwift.getUnityView()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1, execute: {
self.view.addSubview(uView!)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1, execute: {
self.view.sendSubviewToBack(uView!)
})
})
}
}

AWS DynamoDB Object Mapper crashing with SIGABRT

I'm trying to build an iPhone app with swift, I've installed all the dependencies on "connect to your back-end" https://docs.aws.amazon.com/aws-mobile/latest/developerguide/add-aws-mobile-nosql-database.html , I even have the amazon aws login page so it's def connected, just whenenver I add this line:
let dynamoDbObjectMapper = AWSDynamoDBObjectMapper.default()
that it tells me to do in the tutorial, the app crashes on the screen that code is associated to with Thread 1: SIGABRT. Here's my code on the screen it's on.
import UIKit
import MapKit
import AWSCore
import AWSAuthUI
import AWSMobileClient
import AWSUserPoolsSignIn
import AWSDynamoDB
class SampleViewController: UIViewController, CLLocationManagerDelegate {
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
let dynamoDbObjectMapper = AWSDynamoDBObjectMapper.default()
if !AWSSignInManager.sharedInstance().isLoggedIn {
presentAuthUIViewController()
self.navigationController?.isNavigationBarHidden = true
}
}
#IBAction func askPermission(_ sender: UIButton) {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
func presentAuthUIViewController() {
let config = AWSAuthUIConfiguration()
config.enableUserPoolsUI = true
AWSAuthUIViewController.presentViewController(
with: self.navigationController!,
configuration: config, completionHandler: { (provider: AWSSignInProvider, error: Error?) in
if error == nil {
// SignIn succeeded.
} else {
// end user faced error while loggin in, take any required action here.
}
})
}
}
I'd appreciate any help, and can post more information if needed. Thank you so much.
Can you add the following to the awsconfiguration.json after the section that defines "DynamoDBObjectMapper". Replace the 'YourRegion' placeholder below with the region where your Database is located. This is a required section in the awsconfiguration.json file and there may be in a bug in the tool that generates the config.
"DynamoDB": {
"Default": {
"Region": "YourRegion"
}
},

Errors while implementing Chromecast in swift 3

I seem to have a problem implementing ChromeCast features in a project of mine.
I have been trying to implement the GCKDeviceScannerListener Singleton Class on a UIViewController, however its delegate methods are not getting called.
The deviceDidComeOnline method of GCKDeviceScannerListener never gets called.
Instead I have a bunch of error displayed by the chromeCast logger as followed:
+[NSMutableDictionary(GCKAdditions) gck_loadFromCacheWithName:] - Device cache file file:///Users/martin/Library/Developer/CoreSimulator/Devices/318D2E15-C4B0-47D2-97AF-CD560A6063AE/data/Containers/Data/Application/C117BB98-88DA-4586-B119-0683DAD82FEB/Library/Caches/gck_nearby_devices.plist doesn't exist.
+[NSMutableDictionary(GCKAdditions) gck_loadFromCacheWithName:] - Device cache file file:///Users/martin/Library/Developer/CoreSimulator/Devices/318D2E15-C4B0-47D2-97AF-CD560A6063AE/data/Containers/Data/Application/C117BB98-88DA-4586-B119-0683DAD82FEB/Library/Caches/gck_network_cache.plist doesn't exist.
scanning started
+[NSMutableDictionary(GCKAdditions) gck_deleteCacheWithName:] - Device cache file file:///Users/martin/Library/Developer/CoreSimulator/Devices/318D2E15-C4B0-47D2-97AF-CD560A6063AE/data/Containers/Data/Application/C117BB98-88DA-4586-B119-0683DAD82FEB/Library/Caches/gck_device_cache.plist doesn't exist.
+[NSMutableDictionary(GCKAdditions) gck_deleteCacheWithName:] - Device cache file file:///Users/martin/Library/Developer/CoreSimulator/Devices/318D2E15-C4B0-47D2-97AF-CD560A6063AE/data/Containers/Data/Application/C117BB98-88DA-4586-B119-0683DAD82FEB/Library/Caches/gck_device_cache_v1.plist doesn't exist.
+[NSMutableDictionary(GCKAdditions) gck_deleteCacheWithName:] - Device cache file file:///Users/martin/Library/Developer/CoreSimulator/Devices/318D2E15-C4B0-47D2-97AF-CD560A6063AE/data/Containers/Data/Application/C117BB98-88DA-4586-B119-0683DAD82FEB/Library/Caches/gck_device_cache_v2.plist doesn't exist.
+[NSMutableDictionary(GCKAdditions) gck_loadFromCacheWithName:] - Device cache file
file:///Users/martin/Library/Developer/CoreSimulator/Devices/318D2E15-C4B0-47D2-97AF-CD560A6063AE/data/Containers/Data/Application/C117BB98-88DA-4586-B119-0683DAD82FEB/Library/Caches/gck_device_cache_v3.plist doesn't exist
I can't seem to figure out why I have these errors. But it seems that the deviceScanner never even finds my receiver device.
My viewController code is:
class ChromeCastViewController: UIViewController, GCKDeviceScannerListener, GCKDeviceManagerDelegate, GCKMediaControlChannelDelegate{
fileprivate let kCancelTitle = "Cancel"
fileprivate let kDisconnectTitle:String! = "Disconnect"
// Publicly available receiver to demonstrate sending messages - replace this with your
// own custom app ID.
fileprivate let kReceiverAppID = "XXXXXXXXX"
fileprivate lazy var btnImage:UIImage = {
return UIImage(named: "icon-cast-identified.png")!
}()
fileprivate lazy var btnImageselected:UIImage = {
return UIImage(named: "icon-cast-connected.png")!
}()
fileprivate var deviceScanner:GCKDeviceScanner?
fileprivate var deviceManager:GCKDeviceManager?
fileprivate var mediaInformation:GCKMediaInformation?
fileprivate var selectedDevice:GCKDevice?
#IBOutlet weak var googleCastButton: UIBarButtonItem!
#IBOutlet weak var backButton: UIBarButtonItem!
#IBAction func backAction(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
self.startScan()
}
func startScan() {
let filterCriteria = GCKFilterCriteria(forAvailableApplicationWithID: kReceiverAppID)
self.deviceScanner = GCKDeviceScanner(filterCriteria: filterCriteria)
if let deviceScanner = self.deviceScanner {
deviceScanner.add(self)
deviceScanner.startScan()
print("scanning started")
deviceScanner.passiveScan = true
}
}
// MARK: GCKDeviceScannerListener
func deviceDidComeOnline(_ device: GCKDevice) {
print("deviceDidComeOnline")
print("Device found: \(device.friendlyName)");
self.updateButtonStates()
}
func deviceDidGoOffline(_ device: GCKDevice) {
print("deviceDidGoOffline()")
print("Device went away: \(device.friendlyName)");
self.updateButtonStates()
}
func deviceDidChange(_ device: GCKDevice) {
print("deviceDidChange()");
}
func updateButtonStates() {
print("updateButton")
if (deviceScanner!.devices.count > 0) {
// Show the Cast button.
navigationItem.rightBarButtonItems = [googleCastButton!]
if (deviceManager != nil && deviceManager?.connectionState == GCKConnectionState.connected) {
// Show the Cast button in the enabled state.
googleCastButton!.tintColor = UIColor.blue
} else {
// Show the Cast button in the disabled state.
googleCastButton!.tintColor = UIColor.gray
}
} else{
// Don't show Cast button.
navigationItem.rightBarButtonItems = []
}
}
}
Thank you in advance for any help or tips you can give me.
Best regards
UPDATE:
I have modified my code base to follow google v3 guidelines.
I now instantiate a GCKCastContext in AppDelegate in order to use google widgets.
But It seems that GCKCastContext or functionalities associated with the singleton are never called after initialising it. I have tried to add the GCKDiscoveryManagerListener to my AppDelegate to see if was detecting my ChromeCast device.
The code for my AppDelegate is :
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, GCKLoggerDelegate,GCKDiscoveryManagerListener {
var window: UIWindow?
fileprivate let kReceiverAppID = "XXXXXXXXXX"
var discoveryManager: GCKDiscoveryManager
override init(){
let options:GCKCastOptions = GCKCastOptions(receiverApplicationID: kReceiverAppID)
GCKCastContext.setSharedInstanceWith(options)
self.discoveryManager = GCKCastContext.sharedInstance().discoveryManager
super.init()
self.discoveryManager.add(self)
self.discoveryManager.passiveScan = true
self.discoveryManager.startDiscovery()
GCKLogger.sharedInstance().delegate = self
}
.....
func log(fromFunction function: UnsafePointer<Int8>, message: String) {
let functionName = String(cString: function)
print(functionName + " - " + message);
}
func didUpdateDeviceList() {
print("didUpdateDeviceList with \(discoveryManager.deviceCount) devices")
(0..<discoveryManager.deviceCount).forEach { index in
print(index, discoveryManager.device(at: index))
}
}
func didStartDiscoveryForDeviceCategory(deviceCategory: String) {
print("GCKDiscoveryManagerListener: \(deviceCategory)")
print("FOUND: \(self.discoveryManager.hasDiscoveredDevices)")
}
func willUpdateDeviceList(){
print("will update device was called")
}
}
The functions didUpdateDeviceList, didStartDiscoveryForDeviceCategory
, willUpdateDeviceList are never called, meaning no Chrome device is ever found making the widgets unusable.
Thank again for any help

How to implement Nuance Speechkit when using CocoaPods in Swift

Between the pod spec and what is currently on S.O. I had a tough time figuring out how to get speech-to-text working using SpeechKit + CocoaPod + Swift. Finally got it working so figured I'd help the next poor soul that comes looking for help! :)
First install the CocoaPod: https://cocoapods.org/pods/SpeechKit
Add #import <SpeechKit/SpeechKit.h> to your bridging header
Login to Nuance's dev portal and create an app: https://developer.nuance.com/
Clean up the demo code so that is is more organized. I just wanted as much of the code to be in one place as possible so you can see a fully working implementation.
Then create a UIViewController and add the following code with the correct credentials:
import UIKit
import SpeechKit
class SpeechKitDemo: UIViewController, SKTransactionDelegate {
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//!!link this to a corresponding button on the UIViewController in I.B.
#IBAction func tappedButton(sender: AnyObject) {
// All fields are required.
// Your credentials can be found in your Nuance Developers portal, under "Manage My Apps".
let SKSAppKey = "[Get this from the nuance app info page]";
let SKSAppId = "[Get this from the nuance app info page]";
let SKSServerHost = "[Get this from the nuance app info page]";
let SKSServerPort = "[Get this from the nuance app info page]";
let SKSLanguage = "eng-USA";
let SKSServerUrl = "nmsps://\(SKSAppId)#\(SKSServerHost):\(SKSServerPort)"
let session = SKSession(URL: NSURL(string: SKSServerUrl), appToken: SKSAppKey)
//this starts a transaction that listens for voice input
let transaction = session.recognizeWithType(SKTransactionSpeechTypeDictation,
detection: .Short,
language: SKSLanguage,
delegate: self)
print(transaction)
}
//required delegate methods
func transactionDidBeginRecording(transaction: SKTransaction!) { }
func transactionDidFinishRecording(transaction: SKTransaction!) { }
func transaction(transaction: SKTransaction!, didReceiveRecognition recognition: SKRecognition!) {
//Take the best result
let topRecognitionText = recognition.text;
print("Best rec test: \(topRecognitionText)")
//Or iterate through the NBest list
let nBest = recognition.details;
for phrase in (nBest as! [SKRecognizedPhrase]!) {
let text = phrase.text;
let confidence = phrase.confidence;
print("\(confidence): \(text)")
}
}
func transaction(transaction: SKTransaction!, didReceiveServiceResponse response: [NSObject : AnyObject]!) { }
func transaction(transaction: SKTransaction!, didFinishWithSuggestion suggestion: String!) { }
func transaction(transaction: SKTransaction!, didFailWithError error: NSError!, suggestion: String!) { }
}

Resources