I am building an IOS app and it communicates with the JS. So the communication between the two ends must be encrypted. So my main intention is to encrypt from Javascript side and send it to the IOS app mobile end, and the mobile app should decrypt the data. This is how I have done on Javascript side and it works fine as expected,
const key = CryptoJS.enc.Utf8.parse("1111111111111111");
const iv = CryptoJS.enc.Utf8.parse("ui09ji884uh88984");
var encrypted = CryptoJS.AES.encrypt("Hello world",key, {
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
iv: iv
});
console.log("Encrypted data ="+encrypted);
The issue is how I can decrypt this encrypted data in swift using CommonCrypto. Since this is plain base64 text how can we feed it to decryption? The code I have done so far in swift is posted below,
func testCrypt(data data:[UInt8], keyData:[UInt8], ivData:[UInt8], operation:Int) -> [UInt8]? {
let cryptLength = size_t(data.count+kCCBlockSizeAES128)
var cryptData = [UInt8](repeating: 0, count:cryptLength)
let keyLength = size_t(kCCKeySizeAES128)
let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES128)
let options: CCOptions = UInt32(kCCOptionPKCS7Padding)
var numBytesEncrypted :size_t = 0
let cryptStatus = CCCrypt(CCOperation(operation),
algoritm,
options,
keyData,
keyLength,
ivData,
data,
data.count,
&cryptData,
cryptLength,
&numBytesEncrypted)
if UInt32(cryptStatus) == UInt32(kCCSuccess) {
// cryptData.remove
cryptData.removeSubrange(numBytesEncrypted..<cryptData.count)
} else {
print("Error: \(cryptStatus)")
}
return cryptData;
}
This is the way I have called the above method,
let message = "HEY"
let messageData = Array(message.utf8)
let keyData = Array("1111111111111111".utf8)
let ivData = Array("ui09ji884uh88984".utf8)
let str = "SJeOvypKWad9GzUD2GHRig=="
let buf: [UInt8] = Array(str.utf8)
print("BUFF: ",buf)
let encryptedData = testCrypt(data:messageData, keyData:keyData, ivData:ivData, operation:kCCEncrypt)!
let decryptedData = testCrypt(data:buf, keyData:keyData, ivData:ivData, operation:kCCDecrypt)!
var decrypted = String(bytes:decryptedData, encoding:String.Encoding.utf8)!
This works fine if we do both the encryption and decryption and passing the encrypted byte array for decryption. But when I try to convert the encrypted text in to a byte array and passing it to it, an exception occurs. And also the one which I convert (eg: buf) and which the testCrypt returns after encrypting (eg: encryptedData) isn't similar. Please can anyone elaborate this and provide a solution will be greatly appreciated.
Post not yet marked as solved
Hi,
I am developing a dependant watch app and need to pass some data from the phone to watch and vice versa to sync up(Imagine login credentials). So is it secure to pass data as plain text from the mobile to watch app and vice versa? Can hackers or middleman can listen and gain the data within the communication process? Or is the data encrypted by any means default by apple?
Post not yet marked as solved
Hi, I am building a companion watch os app and I want to check before sending a message from watch to phone, whether the app is installed on phone. But whenever I check for whether the companion app is installed it always returns true, even when I uninstall the mobile application (Please note this is a dependant app).
Next I found out that in independant apps, watchconnectivity supports isCompanionAppInstalled, and then I ticked the extension to run as independant and then used the isCompanionAppInstalled. It always returns false regardless of whether the app is installed or not? I am not sure why this not working for either of the above 2 scenarios? How can we find whether the companion IOS app is installed in the device from the watch?
Post not yet marked as solved
Hi,
I am currently building a companion watch application and I use wcsession to exchanges some data within the IOS app and watchOS app. I want to know how much time maximum it would take to send a message and receive a response? Because we can't hold the user infinitely until the watch receives the necessary data? So is it handled from the wcsession itself, like sending out a timeout exception or is it necessary to handle from the developer end? If it is can anyone add a possible solution. Thanks.
Post not yet marked as solved
Sometime I am facing issue in WCSession.
Watchkit app can send ping to iPhone app using WCSession, and it successfully received by the iPhone app but send back the information to watch from iPhone is not received by the watch.
(void)session:(WCSession *)session didReceiveMessage:(NSDictionary<NSString *, id> *)message replyHandler:(void(^)(NSDictionary<NSString *, id> *replyMessage))replyHandler{
//iOS App to watch call back failed
}
then if I kill the watch app then start again it works fine. but after 2-3 hrs again facing connectivity WCSession issue
When trying to turn on the option to unlock my iPhone with my watch I get a communication error. iPhone on iOS 15.1 and watch on 8.1. Both connected as re-paired a number of times and alerts being received on both.
anyone found how to fix this?
Post not yet marked as solved
I have a problem with CoreData.
Is there any way to directly save the data received by WCSession didreceiveuserinfo to CoreData?
Hey,
I am building a watch only application which contains some api requests to be integrated such that data should be shown. I am using the apple watch se and I have turned on the wifi in the watch. But when I am making an api request for example,
Guess I am trying to display a list and inorder to obtain that list I am required to make an api call from the watch app itself and I have written the required code.
There are 4 different scenarios I tested and these are the results
IPhone wifi on, watch wifi on - works
IPhone wifi on, watch wifi off - works
IPhone wifi off, watch wifi on - doesn't work
Both switched off - doesn't work
1,2,4 can be accepted. But I am not sure why 3 is not working. I tested the app store in the watch as well following the above 4 scenarios and still the results are same. So my hypothesis is that it's the behavior of the watch. But i am not sure the reason why 3. is not working since I am making a standalone app and the watch supports wifi or internet connection why can't we directly pull data via the watch internet connectivity? Please someone who can elaborate the reason will be greatly appreciated.
Thanks in advance!
Post not yet marked as solved
Hi! I've been working on a watch app/watch app extension for my iOS app. This app doesn't support running without an iOS app installation. It requires an app to work, it exposes certain controls to execute actions when the counterpart app (iOS app) is opened.
I would like to add a similar interaction like the watchOS camera app and the iOS camera app have: when the iOS app is not active, for example in the background or not opened, show a button in the watch app to open the counterpart app in the foreground.
I've been reading many posts about opening a counterpart app, and it looks like it is not possible, unless using Notifications, so it's the user that starts the action and put the app in the foreground. Some other developers suggests using Handoff, or WatchConnectivity sendMessage with reply handler. I haven't found a way to process an incoming message and transition the iOS app from background to foreground programmatically, not even with custom URLs.
Is it possible for a third-party app not Apple built-in to have a similar experience like camera watchOS and iOS apps?
Which APIs and mechanism should I use to achieve that behavior?
Thanks!
I'm making an Apple Watch app and an iPhone app.
The structure of the app is as follows.
(On Apple Watch) Count the number and store it in Userdefault.(title, number)
(On Apple Watch) Press the 'Count Complete' button to send the title and number data to the iPhone app.
(In the iPhone app) Save the data received from the Apple Watch as CoreData.
Here's the problem.
I don't know the proper way to transfer the data (title, number) generated by the Apple Watch to the iPhone.
Post not yet marked as solved
Install app on phone and watch
Power the watch off
Run the app on the phone.
WCSession.default.isWatchAppInstalled == true
WCSession.isSupported() == true
WCSession.default.isPaired == true
WCSession.default.activationState == .activated
Now I try to run HKHealthStore startWatchApp.
The startWatchApp method's completion never fires.
I'd like to detect that the watch is powered off, so then I do not try to run the startWatchApp method. I can't see a way to detect that the watch is powered off.
Alternatively - I'd like startWatchApp to quickly fail, or - to have some way of cancelling it if it doesn't return quickly.
Any ideas please?
Post not yet marked as solved
Is it possible to share data/settings between an iPhone app and a standalone WatchOS app? Or have the watch app connect to the iOS app to send messages if available? I know how to do it the old way, but I'm moving my Watch app to be standalone and don't see how to communicate or share settings. Thanks
Post not yet marked as solved
In previous versions of Xcode you were able to pick a simulator pair (iOS + watchOS) when running a watch app. In Xcode 12, I cannot find the option for this.
In fact, the only way I seem to be able to test connectivity between my iOS and watchOS is to build and run the iOS app. Then on the simulator open the "Watch" app, navigate to my app name and enable the Show App on Apple Watch option.
This is clearly not a sustainable debug cycle.
How am I able to launch both apps from Xcode without jumping through the above hoops so that I can test the connectivity between the two apps?
Post not yet marked as solved
I am recording accelerometer data using CMSensorRecorder and then trying to retrieve the data in background refresh. However, I am getting the following error:
"[Connection] Error on message reply (sync) for kCLConnectionMessageSensorRecorderGetMetasByDateRange (Connection interrupted)"
Thanks in advance.
Post not yet marked as solved
I'm currently learning how to use WatchConnectivity to send data from the iPhone companion app to the Watch extension.
I watched the talk "Introducing Watch Connectivity" from WWDC 2015 and downloaded the example project provided by Apple which demonstrates the different WC capabilities.
For my specific use case I'm particularly interested in updating the application context on the phone and receiving it on the watch. When I launch the demo app on the phone/watch simulator I see a "Update App Context" button in both UIs.
My understanding is that pressing this button for instance on the phone will call the session's delegate callback didReceiveApplicationContext on the watch on the next app launch.
While this works as expected the other way round, meaning pressing the button on the watch first and receiving the application context on the phone on app launch, I can't get it to work with the context being sent from the phone to the watch. The breakpoint in didReceiveApplicationContext is never hit.
I also noticed that when I set a breakpoint in activationDidCompleteWith on the watch the session property paired and watchAppInstalled are set to false:
However both of these properties are true on the phone:
I did not touch any of the code in the demo app, just set breakpoints to understand what's going on.
My question is: Is it possible to update the application context in both directions?
Post not yet marked as solved
Hi community. It's my first time trying WatchConnectivity kit. When I attempt to send ApplicationContext from phone, my debug print indicates that updateApplicationContext is working correctly. However, I'm having trouble receiving it form the paired watch simulator as nothing is shown on that end. Here are the code for the Phone Extension:
func sendDataToWatch(data: String) {
state.append(data)
do {
NSLog("sent by phone")
try WCSession.default.updateApplicationContext(["currentstate": state])
}
catch {
print(error)
}
}
Here are the code for watch:
func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String: Any]) {
print("Hello")
if let getState = applicationContext["currentstate"] as? [String]{
print("\(getState)")
self.state = getState[0]
}
}
Any suggestion would be appreciated!
Post not yet marked as solved
Apple says that watch OS 8 will work with iOS 14, however when I install 14.6, or even the 14.7 beta, I cannot pair with a watch running watchOS 8. It says my iPhone is out of date. Is this a beta-specific problem?
Post not yet marked as solved
Hello all -
I have built my first watchOS stand-alone app. It tracks moments of motionlessness and if the (adjustable) threshold is not reached in 15, 30 and 45 seconds it triggers an event a, b, c. I am building a string that records the seconds elapsed and the event. May be 100 lines max.
Is there a SIMPLE way to text, email, send, share this string from watchOS w/out building out an entire Eco-system that relies on the paired phone?
I saw a tutorial about writing to icloudDrive, but after a day of returning a nil URL I read: Turns out watchOS does not support iCloud Drive at all, nor does it support the key-value storage iCloud service.
Seriously, if I can just text it to myself I'd be happy.
Note: This is only for proof-of-concept programming - this will never be in production - so hacks are welcome!
Best,
Dan
Post not yet marked as solved
Greetings fellow WatchOS app developers,
On the iOS simulator running 12.5 beta, the method updateApplicationContext() claims that it succeeded, no exception is thrown and yet the WatchOS app, running on a WatchOS 7.4 simulator never gets its
language
session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) method invoked.
Same issue in the other direction: The WatchOs app claims success on updating the iPhone app's application context. Yet nothing arrives.
This works fine on real devices running iOS 14.5 beta and WatchOS 7.4 beta.
Are there any workarounds? Due to Covid-19, I'm working remotely and can't debug on a real device, and need to be able to debug a critical WatchOS 7.4 specific issue.
Thanks in advance!
Post not yet marked as solved
I have implemented a very simple iOS + WatchOS app project, where I test how one can communicate with the other. I will paste the code below, but the idea is really simple. Each app has one single screen with a button and a label. Tapping the button will send a message to the counterpart indicating the timestamp when the message was generated.
If I run the app on the simulators, everything works fine: messages are sent and received correctly on both the iPhone and the Watch. (You can find a reference gif on imgur.com/ + o1ZQTLp).
The problem occurs when I try to run the same apps on my physical devices. Session is activated successfully but messages aren't sent. If I debug the code, I even see the WCSession.isReachable value set to true.
When debugging the WatchKit app, I see errorHandler is called on the func sendMessage(), and the error states:
WatchConnectivity session on paired device is not reachable. However, the errorHandler isn't called from the iPhone app.
Details of my devices:
iOS version: 14.0.1
WatchOS version: 7.0.1
I tested this same code before installing the 7.0.1 WatchOS and it worked without any problems, so I wonder if the update introduced some error on the WatchConnectivity framework.
Code on the iPhone app:
import UIKit
import WatchConnectivity
class ViewController: UIViewController {
		@IBOutlet weak var messageLabel: UILabel!
		fileprivate var wcSession: WCSession!
		override func viewDidLoad() {
				super.viewDidLoad()
				wcSession = WCSession.default
				wcSession.delegate = self
				wcSession.activate()
		}
		@IBAction func sendMessageAction(_ sender: Any) {
				let message = [
						"content": "Message sent from iPhone on \(Date())."
				]
				wcSession.sendMessage(message, replyHandler: nil, errorHandler: { error in
						print("Error when sending message: \(error.localizedDescription)")
				})
		}
}
extension ViewController: WCSessionDelegate {
		func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
				switch activationState {
				case .activated:
						print("WCSession activated successfully")
				case .inactive:
						print("Unable to activate the WCSession. Error: \(error?.localizedDescription ?? "--")")
				case .notActivated:
						print("Unexpected .notActivated state received after trying to activate the WCSession")
				@unknown default:
						print("Unexpected state received after trying to activate the WCSession")
				}
		}
		func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
				guard let content = message["content"] as? String else { return }
				DispatchQueue.main.async {
						self.messageLabel.text = content
				}
		}
		func sessionDidBecomeInactive(_ session: WCSession) {
		}
		func sessionDidDeactivate(_ session: WCSession) {
		}
}
Code on the Watch Kit app:
import WatchKit
import Foundation
import WatchConnectivity
class InterfaceController: WKInterfaceController {
		@IBOutlet weak var messageLabel: WKInterfaceLabel!
		fileprivate var wcSession: WCSession!
		override func awake(withContext context: Any?) {
				wcSession = WCSession.default
				wcSession.delegate = self
				wcSession.activate()
		}
		@IBAction func sendMessageAction() {
				let message = [
						"content": "Message sent from Watch on \(Date())."
				]
				wcSession.sendMessage(message, replyHandler: nil, errorHandler: { error in
						print("Error when sending message: \(error.localizedDescription)")
				})
		}
}
extension InterfaceController: WCSessionDelegate {
		func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
				switch activationState {
				case .activated:
						print("WCSession activated successfully")
				case .inactive:
						print("Unable to activate the WCSession. Error: \(error?.localizedDescription ?? "--")")
				case .notActivated:
						print("Unexpected .notActivated state received after trying to activate the WCSession")
				@unknown default:
						print("Unexpected state received after trying to activate the WCSession")
				}
		}
		func session(_ session: WCSession, didReceiveMessage message: [String: Any]) {
				guard let content = message["content"] as? String else { return }
				messageLabel.setText(content)
		}
}