Sinch client won't start - sinch

Sinch client won't start and it doesn't give an error as to possible reasons.
let uuid = UIDevice.current.identifierForVendor?.uuidString
let client : SINClient = Sinch.client(withApplicationKey: appConstants.sinch_app_key, applicationSecret: appConstants.sinch_secret_key, environmentHost: appConstants.sinch_host, userId: uuid)
client.setSupportCalling(true)
//client.setSupportMessaging(true)
client.start()
client.delegate = self
client.call()?.delegate = self```

What worked was moving Sinch and it's initialisation to the AppDelegate and making it available to other ViewControllers.
So create the Sinch Client once
var sinchObject : SINClient!
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let client : SINClient = Sinch.client(withApplicationKey: appConstants.sinch_app_key, applicationSecret: appConstants.sinch_secret_key, environmentHost: appConstants.sinch_host, userId: "id#id.com")
client.setSupportCalling(true)
client.setSupportMessaging(true)
client.delegate = self
client.start()
sinchObject = client
return true
}
func applicationWillTerminate(_ application: UIApplication) {
sinchObject?.stop()
}
func clientDidStart(_ client: SINClient!) {
print("Start")
}
func clientDidStop(_ client: SINClient!) {
//print("Stop")
}
func clientDidFail(_ client: SINClient!, error: Error!) {
print(error.localizedDescription)
print(error)
print("Fail")
}
And in the needed ViewController
func getSinchClient() -> SINClient {
let mainDelegate = UIApplication.shared.delegate as! AppDelegate
return mainDelegate.sinchObject!
}
func call(){
if (getSinchClient().isStarted()){
sinchCall = getSinchClient().call()?.callUserVideo(withId: callerId)
sinchCall!.delegate = self
}
}
func callDidProgress(_ call: SINCall!) {
print("Call Progress")
}
func callDidEnd(_ call: SINCall!) {
print("Call End")
print(call.details.endCause.rawValue)
}
func callDidAddVideoTrack(_ call: SINCall!) {
print("Call Got Video")
}
func callDidEstablish(_ call: SINCall!) {
print("Call Connected")
}

Related

CMSampleBufferGetDataBuffer() returns nil value - Cocoa Swift

I am trying to capture my system's screen and process the data. But I get nil value for CMSampleBufferGetDataBuffer for the sample buffer I get in captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) delegate method. Any idea? below is my code:
import Cocoa
import AVFoundation
class ViewController: NSViewController, AVCaptureVideoDataOutputSampleBufferDelegate {
private lazy var sampleBufferDelegateQueue = DispatchQueue(label: "VideoCapture")
private lazy var captureSession: AVCaptureSession = {
let session = AVCaptureSession()
session.sessionPreset = .hd1280x720
if let input = AVCaptureScreenInput.init(displayID: CGMainDisplayID()) {
session.addInput(input)
}
let output = AVCaptureVideoDataOutput()
output.videoSettings = [
kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32BGRA,
kCVPixelBufferMetalCompatibilityKey as String: true
]
output.setSampleBufferDelegate(self, queue: self.sampleBufferDelegateQueue)
session.addOutput(output)
return session
}()
#IBAction func startAction(_ sender: Any) {
self.start()
}
override func viewDidLoad() {
super.viewDidLoad()
}
func start() {
guard !self.captureSession.isRunning else {
return
}
self.captureSession.startRunning()
}
func stop() {
guard self.captureSession.isRunning else {
return
}
self.captureSession.stopRunning()
}
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
let blockBuffer = CMSampleBufferGetDataBuffer(sampleBuffer);
print(blockBuffer ?? "nil")
}
}

Reactive Swift consume live data from API - need basic example

I’m new to RxSwift and I’m looking for a basic example of how to print in console live data streaming from an backend. I have a backend which is streaming some dummy data every 1 second, I can see it with a curl request and I want to be able to observe and subscribe and print it out in console automatically, please help!
I assume you are opening a socket connection to your server in order to receive live data. You can use RxWebSocket to handle this data flow. There are examples in the documentation/readme for the API.
https://github.com/daltoniam/Starscream/tree/master/examples/SimpleTest/SimpleTest
import UIKit
import Starscream
class ViewController: UIViewController, WebSocketDelegate {
var socket: WebSocket!
#IBOutlet weak var label: UILabel!
#IBOutlet weak var textField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
var request = URLRequest(url: URL(string: "wss://echo.websocket.org")!)
request.timeoutInterval = 5
socket = WebSocket(request: request)
socket.delegate = self
socket.connect()
}
// MARK: Websocket Delegate Methods.
func websocketDidConnect(socket: WebSocketClient) {
print("websocket is connected")
}
func websocketDidDisconnect(socket: WebSocketClient, error: Error?) {
if let e = error as? WSError {
print("websocket is disconnected: \(e.message)")
} else if let e = error {
print("websocket is disconnected: \(e.localizedDescription)")
} else {
print("websocket disconnected")
}
}
func websocketDidReceiveMessage(socket: WebSocketClient, text: String) {
self.label.text = text
print("Received text: \(text)")
}
func websocketDidReceiveData(socket: WebSocketClient, data: Data) {
print("Received data: \(data.count)")
}
// MARK: Write Text Action
#IBAction func send(_ sender: UIButton) {
socket.write(string: "Hello \(textField.text!)")
}
// MARK: Disconnect Action
#IBAction func disconnect(_ sender: UIBarButtonItem) {
if socket.isConnected {
sender.title = "Connect"
socket.disconnect()
} else {
sender.title = "Disconnect"
socket.connect()
}
}
}
extension URL {
init(staticString string: StaticString) {
guard let url = URL(string: "\(string)") else {
preconditionFailure("Invalid static URL string: \(string)")
}
self = url
}
}

Barcode on swift 4

I'm trying to upgrade mi app to swift 4, but the barcode reader is not working.
I have isolated the barcode reader code, and still not working. The camera works but it does not detect the barcode.
The code worked just fine on swift 3 iOS 10.
This is the complete code
import AVFoundation
import UIKit
class ViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
var captureSession: AVCaptureSession!
var previewLayer: AVCaptureVideoPreviewLayer!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.black
captureSession = AVCaptureSession()
let videoCaptureDevice = AVCaptureDevice.default(for: AVMediaType.video)
let videoInput: AVCaptureDeviceInput
do {
videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice!)
} catch {
return
}
if (captureSession.canAddInput(videoInput)) {
captureSession.addInput(videoInput)
} else {
failed();
return;
}
let metadataOutput = AVCaptureMetadataOutput()
if (captureSession.canAddOutput(metadataOutput)) {
captureSession.addOutput(metadataOutput)
metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
metadataOutput.metadataObjectTypes = [AVMetadataObject.ObjectType.ean8, AVMetadataObject.ObjectType.ean13, AVMetadataObject.ObjectType.pdf417]
} else {
failed()
return
}
previewLayer = AVCaptureVideoPreviewLayer(session: captureSession);
previewLayer.frame = view.layer.bounds;
previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill;
view.layer.addSublayer(previewLayer);
captureSession.startRunning();
}
func failed() {
let ac = UIAlertController(title: "Scanning not supported", message: "Your device does not support scanning a code from an item. Please use a device with a camera.", preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "OK", style: .default))
present(ac, animated: true)
captureSession = nil
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if (captureSession?.isRunning == false) {
captureSession.startRunning();
}
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if (captureSession?.isRunning == true) {
captureSession.stopRunning();
}
}
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {
captureSession.stopRunning()
if let metadataObject = metadataObjects.first {
let readableObject = metadataObject as! AVMetadataMachineReadableCodeObject;
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
found(code: readableObject.stringValue!);
}
dismiss(animated: true)
}
func found(code: String) {
print(code)
}
override var prefersStatusBarHidden: Bool {
return true
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .portrait
}
}
I am using iOS 11 on my iPhone, upgraded to beta 9.
Any idea? Thank you.
I figured it out but Apple didn't make it so obvious. The callback function from the delegate AVCaptureMetadataOutputObjectsDelegate has been renamed and the parameter names are different!
So, replace
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!)
to
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection)
My view controller is now scanning QR Codes as before after this. It has the same parameters but the first parameter name is different. Change the function and parameter names and build/run.
After changing the delegate call back :
From
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!)
To
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection)
I need to set all available types for metadataObjectTypes too as below-
output.metadataObjectTypes=output.availableMetadataObjectTypes
After changing your code from:
func metadataOutput(captureOutput: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {}
to:
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {}
everything works again.
You can use QRCodeScanner83 to scan barcodes:
import QRCodeScanner83
import AVFoundation
...
guard let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(identifier: "CodeScannerViewController") as? CodeScannerViewController else {
return
}
vc.callbackCodeScanned = { code in
print("SCANNED CODE: \(code)")
vc.dismiss(animated: true, completion: nil)
}
self.present(vc, animated: true, completion: nil)
If you need custom UI, then you can nest from CodeScannerViewController and set CodeScannerViewController.delegate to receive updates of the scanner state.

applicationDidFinishLaunching not invoked on Console App

I'm trying to write a simple command line app that can display some info on a notification. But, the Delegate is not being called, and neither is the Notification and I'm not sure what's missing here.
Judging from my output, I think the whole problem stems from the AppDelegate not being instantiated. But I am creating one just before I show call showNotification.
What am I missing here?
src/main.swift
import Foundation
import AppKit
var sema = DispatchSemaphore( value: 0 )
let server: String = "http://jsonip.com"
let port: String = "80"
let path: String = "/"
let todoEndpoint: String = server + ":" + port + path
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
let url = URL(string: todoEndpoint)!
let task = session.dataTask(with: url, completionHandler: {
(data, response, error) in
if error != nil {
print(error!.localizedDescription)
} else {
do {
if let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any]
{
print(json)
let ad = AppDelegate()
ad.showNotification(title: "Title", subtitle: "SubTitle", informativeText: String(describing: json))
sema.signal()
}
} catch {
print("error in JSONSerialization")
}
}
})
print("Resume Task")
task.resume()
print("Wait for Semaphore")
sema.wait()
src/AppDelegate.swift
import Cocoa
class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDelegate {
func applicationDidFinishLaunching(aNotification: Notification) {
NSUserNotificationCenter.default.delegate = self
print("Delegate Self")
}
// NSUserNotificationCenterDelegate implementation
private func userNotificationCenter(center: NSUserNotificationCenter!, didDeliverNotification notification: NSUserNotification!) {
//implementation
}
private func userNotificationCenter(center: NSUserNotificationCenter!, didActivateNotification notification: NSUserNotification!) {
//implementation
}
private func userNotificationCenter(center: NSUserNotificationCenter!, shouldPresentNotification notification: NSUserNotification!) -> Bool {
//implementation
return true
}
func showNotification(title: String, subtitle: String, informativeText: String) -> Void {
let notification: NSUserNotification = NSUserNotification()
print("Show Notification")
notification.title = title
notification.subtitle = subtitle
notification.informativeText = informativeText
//notification.contentImage = contentImage
notification.soundName = NSUserNotificationDefaultSoundName
NSUserNotificationCenter.default.deliver(notification)
print(notification.isPresented)
}
}
Output
Resume Task
Wait for Semaphore
["about": /about, "reject-fascism":
Impeach Trump!, "ip": 110.50.73.141, "Pro!": http://getjsonip.com]
Show Notification
false
Program ended with exit code: 0

Why is In-App-Purchase being restored?

I have a Consumable in-app-purchase in my OS X app that purchases a certain number of coins. However, the second time I purchase the consumable, I get an alert saying that the item has already been purchased and will be restored for free.
Why is this happening with a consumable in-app-purchase?
Here is my IAP code:
typealias RequestProductsCompletionHandler = ([SKProduct]?) -> Void
class IAPHelper: NSObject, SKProductsRequestDelegate{
private var productsRequest: SKProductsRequest?
private var completionHandler: RequestProductsCompletionHandler!
private let productIdentifiers: Set<String>
private var purchasedProductIdentifiers = Set<String>()
init(productIdentifiers: Set<String>){
self.productIdentifiers = productIdentifiers
super.init()
for identifier in productIdentifiers{
let productPurchased = NSUserDefaults.standardUserDefaults().boolForKey(identifier)
if productPurchased{
purchasedProductIdentifiers.insert(identifier)
}
}
}
func requestProducts(completionHandler: RequestProductsCompletionHandler){
self.completionHandler = completionHandler
productsRequest = SKProductsRequest(productIdentifiers: productIdentifiers)
productsRequest?.delegate = self
productsRequest?.start()
}
// MARK: SKProductsRequestDelegate
func productsRequest(request: SKProductsRequest, didReceiveResponse response: SKProductsResponse) {
productsRequest = nil
let skProducts = response.products as! [SKProduct]
completionHandler(skProducts)
completionHandler = nil
}
func request(request: SKRequest, didFailWithError error: NSError) {
productsRequest = nil
print("Error: \(error)\nDescription: \(error.description)")
completionHandler(nil)
completionHandler = nil
}
func buyProduct(product: SKProduct){
let payment = SKPayment.paymentWithProduct(product) as! SKPayment
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
SKPaymentQueue.defaultQueue().addPayment(payment)
}
func productPurchased(productIdentifier: String) -> Bool{
return purchasedProductIdentifiers.contains(productIdentifier)
}
}
extension IAPHelper: SKPaymentTransactionObserver{
func paymentQueue(queue: SKPaymentQueue!, updatedTransactions transactions: [AnyObject]!) {
for transaction in transactions as! [SKPaymentTransaction]{
switch transaction.transactionState{
case SKPaymentTransactionStatePurchased:
completeTransaction(transaction)
case SKPaymentTransactionStateFailed:
failedTransaction(transaction)
default:
break
}
}
}
func completeTransaction(transaction: SKPaymentTransaction){
provideContentForProductIdentifier(transaction.payment.productIdentifier)
SKPaymentQueue.defaultQueue().finishTransaction(transaction)
}
func failedTransaction(transaction: SKPaymentTransaction){
if let errorCode = transaction.error?.code where errorCode != SKErrorPaymentCancelled{
print(transaction.error!.localizedDescription)
}
SKPaymentQueue.defaultQueue().finishTransaction(transaction)
}
func provideContentForProductIdentifier(productIdentifier: String){
//Override in subclass
}
}

Resources