We’ve refreshed the design of the Connect IQ Store website to highlight your apps even better than before. From the product pages to the developer dashboard, everything has a new look and feel. Check it out!
We’ve refreshed the design of the Connect IQ Store website to highlight your apps even better than before. From the product pages to the developer dashboard, everything has a new look and feel. Check it out!
Connect IQ was first announced nine years ago at the ANT+ Symposium. Since that time, we have expanded our support from the original four devices (Vivoactive, Forerunner® 920XT, fēnix® 3 and Epix) to over 100 products.
The Connect IQ team is proud to announce the first beta of System 7. With our new API level of 5.0.0, System 7 represents the maturation of a platform that is now almost a decade old. The improvements in System 7 are meant to help you make better apps for your customers.
The original Venu was the first Connect IQ device with an AMOLED screen and introduced the heuristics to avoid screen burn-in. Newer devices allow watch faces to keep the screen on in “Always On” mode if the screen is using less than 10% of the display pixels.
With API level 5.0.0, we are updating the heuristic from one based on pixels to one based on luminance. Now the screen will stay on if the display is using less than 10% of the total luminance. This allows you to use more pixels.
System 7 also introduces the expansion of some of our communication APIs. In the past, data fields did not support the Communications
module directly, instead requiring a background ServiceDelegate
. In API 5.0.0, data fields can use select Communications APIs within the main application. This allows for data fields that can better integrate with cloud services.
API 5.0.0 devices can also pair with BLE devices using Just Works pairing. The system will remember the bonded devices and allow you to reconnect with devices you have previously bonded with.
System 7 helps you do more with less in a number of different ways. Devices supporting API 5.0.0 have new updates to the system opcodes designed to reduce the code space for common operations. Developers should expect an improvement of 20%– 30% when compiling on new devices.
In addition, one of the fundamentals of Connect IQ is the has
operator, which allows you to check in code if an API exists on a particular device. For example, let’s say you want to check if a device supports the new Complications API and decide based on that to use a new or old implementation. It might look something like this:
if (Toybox has :Complications) { // Register the new callback Complications.registerComplicationChangeCallback(method(:complicationCallback)); } else { // Use the old complication approach timer.start(method(:oldHandler), 1000, true); }
The has
operator allows you to check if a symbol exists in a class or module. In the past, this compiled as a runtime check, but it will now be evaluated at the compile time in the System 7 SDK when possible. This allows the optimizer to eliminate the branch and unnecessary code, as well.
The intention of Monkey Types was to add a type system that allowed the flexibility of Monkey C but didn’t ask for a lot of overhead. While it has mostly succeeded, there is room for improvement.
Monkey Types offers two ways to type containers. Container typing, which borrows heavily from generic containers in Java or other languages, allows the developer to attach type scaffolding to the kinds of elements that can be added or removed from an Array or Dictionary. Dictionary typing allows Dictionary containers to map what keys can be mapped to what values.
Dictionary typing is almost magical, especially for commonly used option dictionaries. By comparison, Array typing feels mechanical. For starters, unlike every other language construct Arrays are not typed implicitly, requiring additional scaffolding where other elements don’t. Container typing also assumes you want a container of a single type, but in Monkey C it is very common to use an array as a cheap struct. This can be seen in getInitialView()
, one of the fundamental APIs:
// So much ugly typing function getInitialView() as Array<Views or InputDelegates>? { return [ new StartView(), new StartDelegate() ] as Array<Views or InputDelegates>; }
We can do better. What we needed was a Dictionary type for linear arrays that allows modeling the type per index. This now can be accomplished with the Tuple:
function getInitialView() as [Views] or [Views, InputDelegates] { // Where did the as clause go? return [ new StartView(), new StartDelegate() ] ; }
Think of Tuple types like Dictionary types, except the key is implied by the order. In this example, the array being returned is automatically typed as a Tuple of types [StartView, StartDelegate]
. This is typed against the allowed return value [Views, InputDelegates]
and found to match.
The rules of Tuple type A matching Tuple type B are as follows:
Arrays created with the [ value, value...]
syntax will now be typed as a Tuple instead of an Array<Any>
. You can use Container types if that better matches the pattern you are implementing, but Tuples have a natural compatibility with Container types. Tuples of type [A, B, C]
shall be instance of Array<A or B or C>
if the types A
, B
, and C
are in the polytype definition of the container type.
function sumArray(x as Array<Numeric>) as Numeric { var result = 0; for (var i = 0; i < x.size(); i++) { result += x[i]; } return result; } function sumThisTuple() as Numeric{ // This should pass type checking because the // Tuple [Number, Number... ] should instanceOf Array<Number> return sumArray([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); }
Tuple types are also mutable. As the underlying array changes with literal indexes, they are modified as long as the type system can keep up.
function foo(x as [Number, Number, Number]) as [Number, Number, Number] { x[1] = "Hello"; // Allowed, type is now [Number, String, Number] return x; // Error, type mismatch }
The following APIs have been changed to use Tuples over Container types:
AppBase.getInitialView() as [Views] or [Views, InputDelegates]
AppBase.getGoalView(goalType as GoalType) as [WatchUi.View]?
AppBase.getGlanceView() as [WatchUi.GlanceView] or [WatchUi.GlanceView, WatchUi.GlanceViewDelegate?] or Null
AppBase.getServiceDelegate() as [System.ServiceDelegate]
AppBase.getSettingsView() as [Views] or [Views, InputDelegates?] or Null
AudioContentProviderApp.getPlaybackConfigurationView() as [Views] or [Views, InputDelegates?] or Null
AudioContentProviderApp.getSyncConfigurationView() as [Views] or [Views, InputDelegates?] or Null
Graphics.getCurrentView() as [WatchUi.View?, WatchUi.InputDelegates?]
ViewLoopFactory.getView(page as Number) as [WatchUi.View] or [WatchUi.View, WatchUi.BehaviorDelegate?] or Null
This should hopefully lead to less boilerplate typing getting in your way.
In addition to Tuples, the Array
type now has a sort
method in API level 5. The default implementation uses the Comparable interface, but you can also implement your own Comparator interface to create your own ordering.
Previously, resource identifiers in the Rez module were typed as Symbol, but in the System 7 SDK they are now typed as Toybox.Lang.ResourceId
. This applies to all devices and not just API 5.0.0 devices.
The System 7 SDK beta is available today from the SDK Manager. You can try the new features using the epix2pro47mmsystem7preview
device. If you have signed up for the device beta program, you will get beta firmware in January.
Happy November! We have many updates across Connect IQ we are excited to share.
The new Connect IQ SDK 6.4.0 and Monkey C Visual Studio Code extension 1.0.10 are now available. By popular demand, we've added a manifest editor into the Visual Studio Code extension. The manifest editor provides a user interface to edit all aspects of the manifest.xml file. We have also added a new Test Explorer that provides a powerful user interface for executing unit tests on your application.
At last year's GDVC we announced we were updating Face It. Those updates are now live and will be available to the following devices getting the latest quarterly update:
From a developer perspective, the most exciting features are the new Face It complications. Developers can now create complications that integrate with Face It using the Complications API. Any app that publishes data can have their information live on the user's watch face. See the Complications chapter to learn more.
Want to try the Test Explorer, or make a Face It complication? Get the SDK and the Visual Studio Code extension and update your apps today!
An update to the Connect IQ mobile SDK for iOS is now available from GitHub. This release addresses an issue with newer devices and iOS 17, as well as other fixes.
Know the real you with the vívoactive® 5 smartwatch, the ultimate on-wrist coach designed to support your goals — whatever they may be. Featuring a bright, colorful display and up to 11 days of battery life, this GPS smartwatch is purpose-built with essential health and fitness features to help you better understand your body.
You’ll find vívoactive 5 support available today from the Connect IQ SDK manager. Update your apps today.
We have just released Connect IQ SDK version 6.3.0, which introduces the wheelchair API, increase sampling rates for accelerometer, gyroscope and magnetometer, and the addition of the Venu 3/3s devices. There are also a handful of bug fixes that were addressed from previous SDKs. Here is the full list of updates and changes:
General Changes
Simulator Changes
AppBase.onActive()
and AppBase.onInactive()
.makeOAuthRequest()
on Windows.Compiler Changes
initialize()
.Today marks the arrival of the new Venu® series smartwatch, the ultimate on-wrist coaches designed to support your goals. With up to 14 days of battery life, these GPS smartwatches are purpose-built with advanced health and fitness features to help you better understand your body. Plus, when paired with your smartphone, they allow you to easily make and take calls right from your wrist.
With the launch of the Venu 3, we are also excited to introduce several new Connect IQ APIs that are outlined below:
The Venu 3 introduces a new task switcher that makes it easy to switch between activities and apps on the device. To take full advantage of the task switcher, you need to utilize the full app lifecycle.
State |
Description |
Launched |
AppBase.onStart() is called when the app is launched or when transitioning from the suspended state. If the app is being resumed, the |
Active |
AppBase.onActive() is called when your app is transitioning from the inactive to active state. Active apps have access defined by the app type. When transitioning from inactive to active, access to sensors, ANT/BLE, will be restored. |
Inactive |
AppBase.onInactive() is called when transitioning from the active to inactive state. |
Suspended |
AppBase.onStop() is called when entering the terminated or suspended state. If the app is being suspended, the |
Based on the state your app is running in, you will have different levels of access to system resources:
|
Active |
Inactive |
Activity Recording |
With permission, you may be allowed to start and stop activity recording. |
If the app is recording an activity, recording will continue. If the app is not recording, it is not allowed to start or stop activity recording. |
GPS |
GPS access may be denied if another app is recording an activity. |
If the app is recording an activity and receiving position events, it will continue to receive events in the inactive state. If the app is not recording an activity, it is blocked from modifying the GPS state. |
ANT |
ANT access may be denied if another app is recording an activity. |
If the app is recording an activity, ANT access is permitted. If the app is not recording an activity, all open channels will be closed and will be reopened when transitioning from inactive to active. |
High Frequency Sensors (Accelerometer, Magnetometer, Gyro) |
If the app is recording an activity, access is permitted. If the app is not recording an activity, access may fail in a non-fatal way. |
If the app is recording an activity, access will be permitted. Otherwise, measurements can be retrieved at a maximum of 10 hz. |
Sensors |
If the app is recording an activity, access is permitted. If the app is not recording an activity, access may fail in a non-fatal way. |
If the app is recording an activity, access will be permitted. Otherwise, sensor access will be limited. |
Attention |
Access is allowed. |
Access is denied. |
The app launcher of the Venu 3 provides separation between activities and apps. If your app has the Fit
permission, it will show in the Activities list.
Venu 3 has a new setting that enlarges the sizes of fonts in menus, glances and application pages to enhance readability.
To add support for enhanced readability mode, check DeviceSettings.isEnhancedReadabilityMode at runtime to see if you should be using larger fonts. Implementing AppBase.onEnhancedReadabilityModeChanged() will let you know if the setting changed while the app was running.
The Venu 3 adds support for users with wheelchairs. When this is enabled, step tracking is replaced with push tracking, and new activities are available to the user.
When wheelchair mode is enabled, ActivityMonitor.Info
will have zeroes for steps
, stepGoal, floorsClimbed, floorsDescended and floorsClimbedGoal and will instead have values in pushes
and pushGoal. Wheelchair mode will also remove COMPLICATION_TYPE_STEPS and COMPLICATION_TYPE_FLOORS_CLIMBED and enable COMPLICATION_TYPE_WHEELCHAIR_PUSHES.
The Venu 3 series is now available from the Connect IQ SDK manager. Update your apps to support them today.
Connect IQ watch faces typically operate in a low-power state where the system requests updates every minute. When the user gestures to look at the watch, the system will request the watch face enter a high-power state. During this period, typically 10 seconds, the watch face can enable timers and play animations. Use this time to add some action to your watch faces.
MIP watch faces by default update once a minute. High-power mode does allow drawing seconds or a second hand for a period, but sometimes the user wants that kind of information available the moment their eyes focus on the watch.
Always-active watch faces can perform a partial update of the screen every second. The update must operate under a 20-millisecond time frame, which does not allow updating the whole screen but can allow for an update on a small portion. For example, the seconds area of this watch face (highlighted in pink) could be updated once a second:
Devices with AMOLED displays typically disable the display when not in use to save power, but they do allow the user to enable an always-on mode. Because long-term display use affects the battery life and can wear down the display, Connect IQ has special rules for AMOLED always-on mode. When the watch face enters always-on mode, the watch face will only update every minute, and each update is limited to using 10% of the available pixels of the display. In addition, a burn-in prevention mechanism will further guide the use of the display on some devices.
Many AMOLED devices have a setting to disable the gesture that returns the watch face to high power mode to save power. To avoid a poor user experience, it is expected that Connect IQ watch faces for AMOLED devices support always-on mode and keep the watch face visible in these cases.
Get the SDK and update your watch faces today.
The Connect IQ Eclipse Plug-in has technically been unsupported since the release of the Visual Studio Code Monkey C Extension, but we've kept it available to allow developers time to transition from Eclipse to Visual Studio Code. As of August 28, the Eclipse plug-in will no longer be available for download. If you haven't already had the chance to shift your Connect IQ development environment to Visual Studio Code, now is a good time!
Thanks
- The Connect IQ Team
We have released Connect IQ SDK version 6.2.2, which contains some fixes for issues found in 6.2.1. Here is the list of changes and updates:
General Changes
Simulator Changes
WatchUi.makeReviewTokenRequest()
on 3.4 devices.Application.onStart()
.Compiler Changes
Array.removeAll()
.