WKInterfaceTable pull to refresh - watchos-2

Is it possible to create pull to refresh action in WKInterfaceTable in watch os 2?
There is one question but its related to watch os 1.
WatchKit pull to refresh

Short Answer:
No, it's not possible.
Long Answer:
All WKInterface Objects are just proxy objects that allows you to send queries to real UI Object. So basically they are not treditional UI Objects.
Connections between real UIs and WKInterface objects are managed by watchOS. What if some WKInterfaceController got deactivated, the connections in it will be disconnected also. In this state, you can't send queries anymore.
You may know that there are two bundles for watch Apps, one takes storyboard and icons, the other one is extension bundle. With sand-box concept, your code(in extension) can't access UI(storyboard bundle sided) directly. The only way to interact is using Interface Builder outlets and sent action.
It(Remote-UI concepts) makes sense for watchOS1 since all the code runs on iPhone. However with some reason, WatchOS2 App also use same strategy. With this restriction, You can't write code that react user interaction to real UI Objects directly likes iOS apps. As I told earlier, You can use pre-defined sent action only.
Since Xcode Interface Builder doesn't provide sent action likes did scroll, You can't write code that react pull down.

Related

Possible to present UIViewController from another app?

This may seem overly ambitious, but I'm exploring the ability to present a view controller from one app in a separate app (both authored by me). I'm not talking about reusing a class, I'm referring to literally presenting a controller from another process over the foremost one.
I believe this is in the realm of XPC on macOS, and how share extensions currently work on iOS. Unfortunately I'm not looking for a share controller though.
Is this at all possible (even using private APIs if I have to)?
Because both apps are sandboxed by iOS, there is no way for either of them to locate and load (something from) the other. Extensions are the only way provided by Apple to have another app perform some action.
Using private APIs will not lift sandbox restrictions. With a jailbroken device, it would be possible to locate the other app. In that case -[NSBundle loadClassNamed:] would allow you to obtain and instantiate a class from a loaded (application) bundle, but it would still be controlled by the process that instantiated it.
So, no, what you ask is not realistically possible for apps that would be distributed to other users than yourself. If it's just for yourself, you might be able to get somewhere with a lot of work on creating, controlling and communicating between processes on jailbroken devices.
If you have your own server, then this is possible. Just have app1 send a trigger to your server, and then your server sends push notification to your app2. when user tap notification, it will open your app2 viewcontroller.

Initiate Parent iOS App Service Call from Today Widget Extension

I am working on a POC iOS application that will eventually be released through an internal enterprise MDM solution. The app itself is pretty straightforward. It makes a quick call to an internal endpoint to return some simple json and then displays it on screen. At the same time, I have an app extension (Today Widget) displaying a small fraction of that data as well.
I have created a shared framework that includes the service calls, as well as any other common code I am using. Unfortunately, the parent app and extension all work perfectly fine if I'm on the internal network where the service endpoints live. However, this app will not always be on our trusted, internal network. As a result, we wrap the build with a secure container provided by our MDM solution and open up traffic to our specific internal endpoints. This works perfectly fine for the app, but our MDM provider doesn't currently provide similar capabilities for App Extensions.
As a result, I am working to come up with creative ways to best ensure the data in my Today Widget is up to date without it directly making a service call. To do so, I am sharing data between the app and extension via an app group, but if the service call is only made from the parent app and the user very rarely accesses the parent app, the data will still be out of date.
In order to simulate making the service call from the app extension to update the data, I would like a way to call the service on behalf of the parent app, which would then update the NSUserDefaults data being shared between app and extension.
So my question: What is the best way for me to initiate that service call in the parent app? Is it even possible? I know Apple provides the 'openURL' method to allow an extension to open it's parent app, but I don't want to actually open the app. I want the app to be running in the background while the extension makes the service call on it's behalf.
I have been looking into the following, but with not much luck:
Parent app has an observer on NSUserDefaults, watching a specific key, that when modified by the app extension will fire off the service call to update the shared data being displayed. Unfortunately, I don't believe this will work, since as long as the parent app is in the background, the NSUserDefaultsDidChangeNotification will not get fired off in the parent app.
Send a local notification from app extension to parent app, telling it to fire off the service call and update data shared via app group. Unfortunately, UIApplication.sharedApplication() is not accessible from an app extension.
Any suggestions of ways to simulate the service call, to give my Today Widget the highest likelihood of being up-to-date with it's information?
Note: Obviously giving Today Widgets access to internal resources has it's own security concerns, but for this POC, the data is non-sensitive and must only live internally..

iOS - Trigger click events outside of the app - like in app drawer

How can you trigger touch and type events outside of your app. I already have created a service that can collect certain data but I can't trigger clicks.
P. S. My requirement is to have a device cloud hosted on the internet and allow people to access them remotely
This is not possible. Apple would never allow such a huge security risk.
You misunderstand how Seetest works. Seetest requires access to your App's binary code, which it instruments:
https://docs.experitest.com/display/public/UFT/iOS+Applications
It then simulates user events by calling event handling methods, e.g. #IBAction handlers. It does not go to the low level that you want, because nothing can unless you violate Apple's usage rules.
EDIT
I was assuming you wanted to write an iOS App that could generate events outside of its sandbox. Instead I think you're referring to Instruments which is controlled by a host.
Because this is a general question, see if this gets you in the right direction:
https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/UsingtheAutomationInstrument/UsingtheAutomationInstrument.html
I have managed to do this using Appium java API. First launch a dummy app, then call driver.back() and from there, you will have full control

Multiple WatchKit Apps For 1 iOS App

According to the Apple Watch Programming Guide, developers are only allowed to include 1 glance in their AppleWatch app. This creates a bit of a challenge for me since my app is an aggregate of different types of data so I'm not sure which data set to include in the glance.
That being said, could I get around this by creating multiple AppleWatch apps for my iOS app which would then allow me to create a single glance for each AppleWatch app?
No. Confirmed one Watch app per iOS app.
There is no support for multiple WatchKit apps per iPhone app at this
time.
- Apple's WatchKit Evangelist
You can implement multiple Glance views depending on the user's context (time and location) using WKInterfaceGroups and hiding/unhiding when necessary.
See my answer to the exact same question here https://stackoverflow.com/a/28214768/3588917
Will a timer work for you? For example, when a certain time elapsed, you can change the UI of the glance to show a different type of data? When a user taps a glance, you will be able to tell what data is showing in the glance at the time and pass relevant contextual data and redirect them to an appropriate interface controller?
"When the user taps a glance, Apple Watch launches the corresponding WatchKit app. Normally, launching the app displays its main interface controller. If you want to display a different interface controller at launch time, call the updateUserActivity:userInfo: method from your glance interface controller and use it to provide contextual information about what the glance is doing. At launch time, your app can use that contextual data to display a different interface controller."

UIApplication.sharedApplication().beginIgnoringInteractionEvents() on Apple Watch

I can not use
UIApplication.sharedApplication().beginIgnoringInteractionEvents()
in WatchKit Extension, I have error:
'sharedApplication()' is unavailable: Use view controller based solutions where appropriate instead.
Is there some alternative ?
The short answer is: No there isn't.
The long answer:
Please keep in mind that the extension is not executed on the watch but on your phone. So if you would call UIApplication.sharedApplication() it would return you the application of the extension on your phone, anyway! Everything you do inside your extension is stuff that manipulates the extension on your phone. The only exception from this are the WatchKit methods. And even they are basically calls that are converted into instructions that are send over bluetooth to tell the watch what to do. At no time you can write code that executes on the watch!
You have no control what so ever about what the watch does with the instructions you send to it. You are basically acting as a server talking to a client and you have no control over the client. You should send as little instructions as possible and once you send them, your task is done, the rest is up to the watch.
That being said, you should carefully plan your UI in a way that you do not need any calls that manipulate the event delivery. You should focus on simple 'if user taps x I do y' interaction.
Another thing to keep in mind is, that your extension can not communicate with your main iOS app. You can create a shared app group between your iOS app and your watch extension to share data between them, however you can not directly communicate with your app. If you want to use parts of your apps logic, extract the module in question into a framework (this has become very easy with Xcode 6) and use the framework in both, your app and your extension.

Resources