Post not yet marked as solved
I developed an independent Apple Watch that can access network resources on its own using NSURLSession without going through the iPhone. This works fine if the iPhone is on, but if I turn the iPhone off it is not able to connect. Why does my app lose network connectivity when the iPhone is off even though it's a standalone app and the Watch is connected to my WIFI? Is there anything special I need to do to get this working? It appears that no apps work with the internet when the iPhone is off. WIFI is enabled and connected to my WIFI network under the Settings on the watch
Post not yet marked as solved
I am using WatchConnectivity to send messages between my swift iPhone / watch app.
When I receive a message on the iPhone, from the watch, I need to jump to the main thread.
The problem is; when the iPhone is in an inactive/not running state it never seems to complete that action.
The iPhone receives the message, but when it tries to dispatchQueue.main.async{} , it seems to time out. The code inside .async{} never gets called.
Here’s the code where it receives the message on the iPhone:
func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
print("Message recieved: ", message)
// We always make it to at least here, no matter what state the application is in.
DispatchQueue.main.async {
// This code is never called if the app is in an inactive/not running state.
// Do something...
}
}
Post not yet marked as solved
I have a watch app which communicates with the iPhone app fine. But when running the WCSession from the Intent extension (used for Siri) I'm getting following in the console logs:
Error Domain=WCErrorDomain Code=7018 "Companion app is not installed."
Can the Watch Intent extension communicate with iPhone app - if so how can I enable it?
Post not yet marked as solved
Hey there,
I am new to Swift, Objective C, however have a reasonable amount of experience in other programming languages.
Want to get some thoughts on where to begin for an app idea I have. I want to build a WatchOS app that vibrates to a metronome. However, the catch is, I need it to be synchronised to a Digital Audio Workstation (Ableton Live) running on a Macbook.
A bit of background on the use-case. I play in a band, and we run backing tracks on a MacBook. In order for the band to play in time to the backing tracks, we are all fed metronome clicks in our ears. I want to be able to feel the metronome on my apple watch instead.
I was thinking about hooking into the IAC driver. In my DAW software, sending midi notes (that's the metronome) to an IAC driver channel, and feeding that through to the Apple Watch to vibrate each time a midi note is detected.
Obviously, this would need to have as little latency as possible because we all need to play in sync. Some of us may still be on in-ears, so audible metronome clicks and the watch vibrations need to be completely in sync.
Anyway, I am confident in going off and researching and developing the many individual components of this build, but I just need some guidance about my solution design and whether something like this is even possible.
Many thanks!
Post not yet marked as solved
confirguration nécessaire pour utiliser apple watch se gps cellular: IOS 15 ou IOS 14 (jai 1 Iphone 6s plus et IOS 14.86)
merci
Post not yet marked as solved
The ios side cannot accept the data sent by the watchOS side
// watch os InterfaceController
import WatchKit
import Foundation
import WatchConnectivity
class InterfaceController: WKInterfaceController, WCSessionDelegate {
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
}
@IBOutlet var label: WKInterfaceLabel!
@IBOutlet var button: WKInterfaceButton!
override func awake(withContext context: Any?) {
// Configure interface objects here.
super.awake(withContext: context)
if(WCSession.isSupported()){
let session = WCSession.default;
session.delegate = self;
session.activate();
}
label.setText("")
// button.setTitle("Send Data")
}
@IBAction func sendData() {
print("send data")
let session = WCSession.default;
if(session.isReachable){
DispatchQueue.main.async {
print("Sending data from watch...")
session.transferUserInfo(["method": "sendDataToFlutter"])
}
}else{
print("App not reachable...")
}
}
override func willActivate() {
// This method is called when watch view controller is about to be visible to user
super.willActivate()
}
override func didDeactivate() {
// This method is called when watch view controller is no longer visible
super.didDeactivate()
}
func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
self.label.setText(message["message"] as! String)
}
}
// AppDelegate.h
#import <Flutter/Flutter.h>
#import <UIKit/UIKit.h>
#import <WatchConnectivity/WatchConnectivity.h>
@interface WTUserInfoHandler : NSObject <FlutterStreamHandler>
@end
@interface AppDelegate : FlutterAppDelegate<WCSessionDelegate>
@end
// AppDelegate.m
#include "AppDelegate.h"
#include "GeneratedPluginRegistrant.h"
#import "Runner-Swift.h"
@implementation WTUserInfoHandler
FlutterEventSink sink;
NSDictionary *info;
- (void) updateUserInfo:(nonnull NSDictionary<NSString *, id> *)userInfo{
NSLog(@"Update Recieved");
if(info != userInfo){
info = userInfo;
if(sink!=nil){
sink(@[userInfo]);
}
}
}
- (FlutterError*)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)eventSink {
NSLog(@"Adding Flutter Listener");
sink = eventSink;
return nil;
}
- (FlutterError*)onCancelWithArguments:(id)arguments {
NSLog(@"Removing Flutter Listener");
if(sink!=nil){
sink = nil;
}
return nil;
}
@end
@interface AppDelegate ()
@property(nonatomic, strong)WCSession *session;
@property(nonatomic, strong)WTUserInfoHandler* userInfoStreamHandler;
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if (@available(iOS 10.0, *)) {
[UNUserNotificationCenter currentNotificationCenter].delegate = (id<UNUserNotificationCenterDelegate>) self;
}
[GeneratedPluginRegistrant registerWithRegistry:self];
[self initFlutterMethodChannelWatchSession];
// Override point for customization after application launch.
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
# pragma mark -----------------WCSessionDelegate start------------------------
-(void) initFlutterMethodChannelWatchSession {
FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController;
FlutterMethodChannel *tipinfoChannel = [FlutterMethodChannel
methodChannelWithName:@"com.upcwangying.apps.flutter.boilerplate"
binaryMessenger: controller];
[tipinfoChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
// activate Session
if([@"initWatchSession" isEqualToString:call.method]){
[self activateSession];
result(@"WatchTips Activated");
}else if([@"sendDataToWatch" isEqualToString:call.method]){
[self sendDataToWatch: call.arguments];
} else {
result(FlutterMethodNotImplemented);;
}
}];
}
- (void)sendDataToWatch:(NSString *) data {
if (self.session != nil) {
if (self.session.isPaired && self.session.isReachable) {
dispatch_async(dispatch_get_main_queue(), ^{
[self.session sendMessage:@{@"message": data} replyHandler: nil errorHandler: nil];
});
}
}
}
- (void)session:(WCSession *)session activationDidCompleteWithState:(WCSessionActivationState)activationState error:(nullable NSError *)error {
}
/** ------------------------- iOS App State For Watch ------------------------ */
/** Called when the session can no longer be used to modify or add any new transfers and, all interactive messages will be cancelled, but delegate callbacks for background transfers can still occur. This will happen when the selected watch is being changed. */
- (void)sessionDidBecomeInactive:(WCSession *)session {
}
/** Called when all delegate callbacks for the previously selected watch has occurred. The session can be re-activated for the now selected watch using activateSession. */
- (void)sessionDidDeactivate:(WCSession *)session {}
// Event triggered when userInfo Rxd
- (void)session:(nonnull WCSession *)session didReceiveUserInfo:(nonnull NSDictionary<NSString *, id> *)userInfo
{
if(self.userInfoStreamHandler != nil){
[self.userInfoStreamHandler updateUserInfo:userInfo];
}
}
// Method used to enable the Watch session
- (void)activateSession
{
[self activateChannel];
[self watchSession];
}
// create our eventChannel
-(FlutterEventChannel *) activateChannel {
self.userInfoStreamHandler = [[WTUserInfoHandler alloc] init];
FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController;
FlutterEventChannel *eventChannel = [FlutterEventChannel eventChannelWithName:@"com.upcwangying.apps.flutter.boilerplate/watchdata" binaryMessenger:controller];
[eventChannel setStreamHandler:(NSObject<FlutterStreamHandler> * _Nullable) self.userInfoStreamHandler ];
return eventChannel;
}
// activate session
- (WCSession *)watchSession
{
if (self.session == nil) {
if ([WCSession isSupported]) {
self.session = [WCSession defaultSession];
[self.session setDelegate:self];
[self.session activateSession];
} else {
NSLog(@"Error - Watch Connectivity NOT supported");
}
}
return self.session;
}
- (void)dealloc
{
if (self.session != nil) {
[self.session setDelegate:nil];
}
}
# pragma mark -----------------WCSessionDelegate end------------------------
@end
Post not yet marked as solved
I'm new to Apple watch mainly because I am trying to develop a companion app. New as a user and a developer for Apple Watch.
I'm following an official Apple tutorial, but it seems to make a lot of assumptions.
App groups
Complications (horrible choice of terminology?)
In the "Update Current Complications from iOS apps" step, I have no idea how to do what it's saying.
https://developer.apple.com/documentation/watchconnectivity/using_watch_connectivity_to_communicate_between_your_apple_watch_app_and_iphone_app
How do I choose a "Modular" watch face? What constitutes a "Modular" watch face?
I deep pressed the current (default) face and it went into an edit mode, but swiping right didn't do anything. Swiping left offered more options, but I don't think it aligns with what it's saying to do.
Stuck at 1 & 2
Stuck at 1 & 2
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
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, I have created a watch only app and would need to convert it to a dependant watch app since I need to exchange data via watch connectivity? How can we convert such kind of an app? Is it possible without creating a new app, by only changing the required settings in the existing app?
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
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
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.
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
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!