Why is session.paired unavailable? - ios

In an iOS app, I've created a swift file named DataCoordinator with the following code:
import UIKit
import WatchConnectivity
class DataCoordinator: NSObject {
func test(session:WCSession!) {
if session.paired == true {
//...
}
}
}
When I try to build, I get this error:
'paired' is unavailable
'paired' has been explicitly marked unavailable here
This is in the iOS app and not the in the WatchOS app. It works fine if I use the above code in a ViewController class.

Related

Delegate methods not being called in swift class

I'm integrating an SDK that tracks location points.
The SDK demo app has the SDK framework loaded, and then a UIViewController that extends the SDK delegate. The SDK calls certain delegate functions as the user moves around - these all work fine in the demo app from the SDK provider. All the delegate callback functions, like processStart are inside the TripsViewController: UIViewController, TheSDKSwiftDelegate
Example:
import TheSDKSwift
final class TripsViewController: UIViewController, TheSDKSwiftDelegate {
...
TheSDKSwift.setup(with: configuration, delegate: self, completionHandler: {success, error in
if success {
successBlock()
} else {
failureBlock(error)
}
})
...
// TheSDK Delegate callbacks
func processStart(ofDrive startInfo: DriveStartInfo) {
self.driveStatusLabel.text = "Driving"
if self.isAccidentEnabled() {
self.mockAccidentButton.isEnabled = true
}
let dateString = DateFormatter.shortStyleFormatter.string(from: Date(timeIntervalSince1970: TimeInterval(startInfo.startTimestamp/1000 )))
NotificationManager.displayNotification(message: "Trip Started: \(dateString)")
}
}
So during the normal running of the SDK, it then calls back to the processStart method to provide info on what's happening.
Now, in my own app, I can't have these functions/delegates in UIViewController. I need to have them in a separate Swift file and call the functions from another controller. When I do that, my SDK initializes, but the delegate methods don't get called by the SDK while it's running, whereas the delegate methods DO get called when everything is in on UIViewController extending the delegate. Just not when I put it in my own swift file.
Here's a short snippet of what I'm doing:
import Foundation
import Capacitor
#objc(TheSDKPlugin)
public class TheSDKPlugin: CAPPlugin {
#objc func SetupSDK(_ call: CAPPluginCall) {
TheSDKPluginWrapper().StartSDK()
}
So TheSDKPluginiWrapper().StartSDK() gets called.
import Foundation
import TheSDKSwift
import Capacitor
class TheSDKPluginWrapper: NSObject, TheSDKSwiftDelegate {
...
TheSDKSwift.setup(with: configuration, delegate: self, completionHandler: {success, error in
if success {
successBlock()
} else {
failureBlock(error)
}
})
...
// TheSDK Delegate callbacks
func processStart(ofDrive startInfo: DriveStartInfo) {
self.driveStatusLabel.text = "Driving"
if self.isAccidentEnabled() {
self.mockAccidentButton.isEnabled = true
}
let dateString = DateFormatter.shortStyleFormatter.string(from: Date(timeIntervalSince1970: TimeInterval(startInfo.startTimestamp/1000 )))
NotificationManager.displayNotification(message: "Trip Started: \(dateString)")
}
}
Again, SDK initializes successfully. But now, SDK never calls the delegate method in TheSDKPluginiWrapper().
How do I retain the delegate throughout, so that SDK delegate methods get called in my swift file, same way it gets called when everything is in UIViewController?
If you want the delegate methods in a separate file, you can just define them as an extension to the class:
extension TripsViewController: TheSDKSwiftDelegate {
// TheSDK Delegate callbacks
func processStart(ofDrive startInfo: DriveStartInfo) {
}
...
}

Built.io integration failed in iOS application due to ambiguous method call error

I am trying to integrate built.io in iOS application using Xcode 9.1 and swift 4 but it failed due to ambiguous save call error, although I have only called this method once still it says ambiguous call. I am unable to identify the problem.
I referred this link to integrate sdk in iOS :
Code used is
import UIKit
import Contentstack
import BuiltIO
class ViewController: UIViewController {
func built(){
var builtApplication : BuiltApplication = Built.application(withAPIKey: "")
var pc : BuiltClass = builtApplication.class(withUID: "test")
var projectObject:BuiltObject = pc.object()
projectObject.save { (responseType, err) in //ambiguous error here on save call
if err != nil {
print("Err")
} else {
print("Success")
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
}
I have installed sdk in project using cocoapod. Below image contains application screenshot that shows error. I am using BuiltObject class object to call save method but when I jump into save method it takes me to method of BuiltKeyStore class, and I completely don't understand why? Please help, Thanks in advance 🙂
You need to pass completionBlock as a parameter instead of inline.
Try the below code which works fine for Swift 3.2 & 4,
let completionBlock:BuiltRequestCompletionHandler = { (responseType:BuiltResponseType, error:Error?) in
if error != nil {
print("Err")
} else {
print("Success")
}
}
projectObject.save(completionBlock)
Give it a try that should definitely work.

Nearby Bluetooth devices using Swift 3.0

I'm looking for a way to programmatically list any nearby Bluetooth devices (discoverable) that my device finds. I have not been able to find any information or tutorials regarding performing this call in Swift 3.0. This Q-A post discusses finding these devices using Swift 1.0 and building in Xcode 6, rather than the latest version 8.
I did my best to try to make my code into the 3.0 Syntax from the 1.0, but while running the following code, nothing is returned in the Playground:
import Cocoa
import IOBluetooth
import PlaygroundSupport
class BlueDelegate : IOBluetoothDeviceInquiryDelegate {
func deviceInquiryComplete(_ sender: IOBluetoothDeviceInquiry, error: IOReturn, aborted: Bool) {
aborted
print("called")
let devices = sender.foundDevices()
for device : Any? in devices! {
if let thingy = device as? IOBluetoothDevice {
thingy.getAddress()
}
}
}
}
var delegate = BlueDelegate()
var inquiry = IOBluetoothDeviceInquiry(delegate: delegate)
inquiry?.start()
PlaygroundPage.current.needsIndefiniteExecution = true
Using IOBluetooth the Correct Way
The following code works flawlessly in Xcode Version 8.2.1 (8C1002), Swift 3.0. There are a few lines that aren't required, such as the entire method of deviceInquiryStarted.
Update: These usages still work as of Xcode 9.2 (9B55) and Swift 4.
Playground
import Cocoa
import IOBluetooth
import PlaygroundSupport
class BlueDelegate : IOBluetoothDeviceInquiryDelegate {
func deviceInquiryStarted(_ sender: IOBluetoothDeviceInquiry) {
print("Inquiry Started...")
//optional, but can notify you when the inquiry has started.
}
func deviceInquiryDeviceFound(_ sender: IOBluetoothDeviceInquiry, device: IOBluetoothDevice) {
print("\(device.addressString!)")
}
func deviceInquiryComplete(_ sender: IOBluetoothDeviceInquiry!, error: IOReturn, aborted: Bool) {
//optional, but can notify you once the inquiry is completed.
}
}
var delegate = BlueDelegate()
var ibdi = IOBluetoothDeviceInquiry(delegate: delegate)
ibdi?.updateNewDeviceNames = true
ibdi?.start()
PlaygroundPage.current.needsIndefiniteExecution = true
Project-Application Usage
import Cocoa
import IOBluetooth
import ...
class BlueDelegate : IOBluetoothDeviceInquiryDelegate {
func deviceInquiryStarted(_ sender: IOBluetoothDeviceInquiry) {
print("Inquiry Started...")
}
func deviceInquiryDeviceFound(_ sender: IOBluetoothDeviceInquiry, device: IOBluetoothDevice) {
print("\(device.addressString!)")
}
}
//other classes here:
//reference the following outside of any class:
var delegate = BlueDelegate()
var ibdi = IOBluetoothDeviceInquiry(delegate: delegate)
//refer to these specifically inside of any class:
ibdi?.updateNewDeviceNames = true
ibdi?.start() //recommended under after an action-button press.
Explanation
The issue I was originally faced with was trying to access the information as the inquiry was still in process.
When I accessed it, under many different occasions my playground would hang and I would be forced to force quit both Xcode.app, and com.apple.CoreSimulator.CoreSimulatorService from the Activity Monitor. I lead myself to believe that this was just a Playground bug, only to learn that my application would crash once the inquiry finished.
As Apple's API Reference states:
Important Note: DO NOT perform remote name requests on devices from delegate methods or while this object is in use. If you wish to do your own remote name requests on devices, do them after you have stopped this object. If you do not heed this warning, you could potentially deadlock your process.
Which entirely explained my issue. Rather than directly asking for the IOBluetoothDevice information from the sender.foundDevices() method (which I believe may not have been updating..?) I simply used the parameters built into the function to mention that it was indeed an IOBluetoothDevice object, and simply to ask for that information to be printed.
Final Note
I hope that this Q/A I've created helps others in need when using IOBluetooth in Swift. The lack of any tutorials and the high amounts of outdated, Objective-C code made finding this information very challenging. I'd like to thank #RobNapier for the support on trying to find the answer to this riddle in the beginning. I'd also like to thank NotMyName for the reply on my post on the Apple Developer Forums.
I will be exploring the usage of this in an iOS device more sooner than later!

Cannot call value of non-function type UIApplication when trying to open google maps URL

I'm new to swift programming and I stumbled upon a problem which can't seem to find a solution after searching the web.
What i'm trying to do is when a button is tapped in my application I want the Google maps app to launch but after implementing the code I get the error: Cannot call value of non-function type UIApplication
Am I missing something?
import UIKit
import GoogleMaps
class MapDisplayViewController: UIViewController, GMSMapViewDelegate, CLLocationManagerDelegate, UIApplicationDelegate {
#IBOutlet weak var openDirections: UIButton!
#IBAction func openMapsDirection(_ sender: UIButton!) {
if (UIApplication.sharedApplication().canOpenURL(NSURL(string:"comgooglemaps://")!)) {
UIApplication.sharedApplication().openURL(NSURL(string:
"comgooglemaps://?center=40.765819,-73.975866&zoom=14&views=traffic")!)
} else {
print("Can't use comgooglemaps://");
}
}
}
In Swift 3 sharedApplication() has been replaced with a property called shared.
Try updating your code:
if (UIApplication.shared.canOpenURL(NSURL(string:"comgooglemaps://")!)) {
UIApplication.shared.openURL(NSURL(string:
"comgooglemaps://?center=40.765819,-73.975866&zoom=14&views=traffic")!)
} else {
print("Can't use comgooglemaps://");
}
"comgooglemaps:// and comgooglemaps-x-callback:// - These schemes allow you to launch the Google Maps app for iOS and perform one of several actions"
Please make sure that your device already installed Google Maps app.
https://developers.google.com/maps/documentation/ios-sdk/urlscheme
Hope this will help you.

watchOS 2 Reachability in Swift

I have looked around at some of the similar answers but none of these seem to be helping me.
I seem to be having a problem with my application. I have created the single view application and also added in the WCSessionDelegate into my extension.
import WatchKit
class ExtensionDelegate: NSObject, WKExtensionDelegate, WCSessionDelegate { }
I have also checked the session if the session is not there and told it to print out if it cant find it
guard WCSession.isSupported() else {
print("Session is not supported")
return
}
let session = WCSession.defaultSession()
session.delegate = self
session.activateSession()
However I am still getting a No WatchConnectivity error. I'm confused as If the session is working then I think I have it coded right?
Answer
Whilst waiting for your code, I think I can see the issue. Where you have declared the session delegate as a delegate here:
import WatchKit
class ExtensionDelegate: NSObject, WKExtensionDelegate, WCSessionDelegate { }
You need to also import WatchConnectivity
like so:
import WatchKit
import WatchConnectivity
class ExtensionDelegate: NSObject, WKExtensionDelegate, WCSessionDelegate { }
Let me know if his helps!
Tutorial
There is a tutorial which explains exactly this issue: http://ios-blog.co.uk/tutorials/swift/watchos-2-checking-reachability/
Plugin
Also in the same search is a nift plugin you can use: https://github.com/ashleymills/Reachability.swift - This would be my option if you're not confident enough
Tip
(Google is your friend)

Resources