📜 ⬆️ ⬇️

Application Development for Apple Watch (iPhone and iPad) using Wolfram Language (Mathematica)


Translation of Stephen Wolfram's post " Instant Apps for the Apple Watch with the Wolfram Language ".
I express my deep gratitude to Kirill Guzenko for his help in translating.

My goal is to bring programming to a new level with the help of Wolfram Language . And over the past year (see the article on Habrahabr " Stephen Wolfram: Frontiers of computational thinking (report from the SXSW festival) ") we have expanded the ways of using and deploying the language - on a desktop computer, in the cloud, mobile and embedded platforms, etc. A what about wearable gadgets? And, in particular, about the Apple Watch? A few days ago I decided to see what can be done here. So I freed up my day and started writing code.

The idea was to write code using the Wolfram Programming Cloud , but instead of creating a web application or a web API, I needed to get an application for the Apple Watch. And, which is quite convenient - the first, preliminary, version of our Wolfram Cloud app is now available on the App Store:


')
It allows you to unload applications from Wolfram Cloud immediately on the iPhone, iPad and Apple Watch.



In a sense, it was adventure programming. Apple Watch just came out, and the Wolfram Cloud app was still only a preliminary version. However, for the last 30 years I have been creating an advanced development environment for the Wolfram Language. And I am pleased to note the fact that it does not take you long to start getting interesting Wolfram Language applications running on the Apple Watch. And in less than a day of work - with the help of a small team - I developed 25 applications compatible with the clock:



I created all these applications by following a few steps - first programming them in the Wolfram Programming Cloud (on the website or in the desktop version), then deploying them in the Wolfram Cloud and connecting to the Apple Watch via the Wolfram Cloud app. And, although the applications were designed for the Apple Watch, you can, in fact, also use them through a browser or on the phone. There are links to web versions of applications that are presented in this post. To get these applications to your phone or watch, simply go to this page and follow the instructions.



This page also has all the source code of these applications on Wolfram Language, and you can use any system of working with Wolfram Language - Wolfram Programming Cloud (including free of charge), Mathematica and so on - to experiment with the code yourself and, possibly, , post your version of any application.

My first app for Apple Watch


So how does all this work? For the first time working with the Apple Watch, I decided to write a simple test application that produces one random number. The main Wolfram Language code for this task is quite simple:

In [1]: = RandomInteger [1000]

Let the numbers on the clock be big and bold, and in general, with a random color:

In [2]: = Style [RandomInteger [1000], Bold, 30, RandomColor []]

We can immediately upload all this to the cloud with:

In [3]: = CloudDeploy [Delayed [Style [RandomInteger [1000], Bold, 250, RandomColor []], & quot; PNG & quot;], Permissions -> & quot; Public & quot;]

And, if you click on this link in a web browser, you will see a web application that creates a web page with a random number. ( Delayed in the code delays the calculations until nobody has entered the page or until it has been updated, so you will receive a new random number each time.)

How to send all this to Apple Watch? First, all of this should go first to the iPhone. And it is easy. Because everything that you have uploaded to the Wolfram Cloud is fully accessible on the iPhone through the Wolfram Cloud app. To make this application easy to find, add an icon and a name. And if in the end all this will work on the clock, then it is worth placing it on a black background:

In[4]:= CloudDeploy[Delayed[ExpressionCell[Style[RandomInteger[1000], Bold, 250, RandomColor[]], Background -> Black], "PNG"], "WatchApps/RandomNumber", IconRules -> WordCloud[RandomInteger[10, 20]]]

And now, if you follow this link through a browser, you will see an open version of the application there. Inside the Wolfram Cloud app on the iPhone, the application appears in the WatchApps folder:

Deploy that RandomNumber app, and it will appear on your phone

Now, if you click on the application icon, you will run the Wolfram Language code in the Wolfram Cloud and again the random number displayed on the phone will be issued:

The RandomNumber app works fine on the phone, but of course is sized for the Apple Watch screen

If you want to start the application again and get a new random number, just pull down at the top of the screen.

To get the app on the clock, go back to the list of apps and click on the clock icon at the top and select the app. This will display it on the clock in the list of those applications that are associated with the phone:

That's all it takes to get the app onto your watch

Now just click the RandomNumber app. In this case, the Wolfram Language code will be launched in the Wolfram Cloud, and then a random number will be displayed on the clock:

And here it is running on the watch--it's that easy

Random applications


With Wolfram Language it is very easy to create all sorts of "random" applications. Here is the key part of the Coin Flip app coin flip app :

In[5]:= RandomChoice[{image:heads, image:tails}]

This is all that is needed to deploy the application on the Internet, on mobile devices and watches:

In[6]:= CloudDeploy[Delayed[ExpressionCell[RandomChoice[{image:heads, image:tails}], Background -> Black], "PNG"], "WatchApps/CoinFlip", IconRules -> image:heads]

Someone might say that it is impractical to use this whole complex set of technologies for such tasks. In the end, because it is easy - just throw a regular coin. But this suggests that you have it somewhere (for me, for example, they do not exist). In addition, the Coin Flip app will produce a better pseudo-random sequence.

How about playing rock-paper-scissors with your watch? The main code for this task is again quite simple:

In[7]:= RandomChoice[{image:rock, image:paper, image:scissors}]

There is a huge amount of knowledge embedded in Wolfram Language - and somewhere in the far corner there is knowledge that makes it very easy to create an application with the output of the random Pokemon Random Pokemon app :

In[8]:= EntityValue[EntityValue["Pokemon", "RandomEntity"], {"Image", "Name"}]

Here is how it works on the clock:

Stats pop quiz: How many random displays will it take, on average, before you catch 'em all?

Let's try something now with more complex Wolfram Language code. Here, for example, is the inventor of the words Word Inventor app , which creates a word from random vowels and consonants, alternating between them (the resulting words often sound like the names of Pokemon or some technical start-ups).

In[9]:= vowels = {"a", "e", "i", "o", "u"}; consonants = Complement[CharacterRange["a", "z"], vowels]; Style[StringJoin[Flatten[Table[{RandomChoice[consonants], RandomChoice[vowels]}, {3}]]], 40]

Clock that shows time


For lack of other things, people, presumably, will want to use the watch for their intended purpose. And since we are in the modern world with the Internet - even in the clock now we can’t do without a couple of cats. Below is the Kitty Clock code on the Wolfram Language:

In[10]:= ClockGauge[Now, PlotTheme -> "Minimal", GaugeMarkers -> {image:graycat, image:orangecat, None}, Background -> Black, TicksStyle -> White]

And on the watch itself, it looks like this:

You can has kitty clock...

With this watch you can get crazy things. Based on our recent (see the article on Habrahabr " 3/14/15 9:26:53 The celebration of the" Day of Pi "century, as well as the story of how to get your very personal piece of pi ") and the very popular site My Pi Day , created in honor of the day of Pi, below presents a slightly more complex code for Pi watches , in which the current time is displayed in the context of finding these figures in Pi number:

In[11]:= pi = Characters[ToString[N[Pi, 65000]]]; time = Characters[DateString[{"Hour12", "Minute"}]]; pos = First[SequencePosition[pi, time]]; Style[Grid[Partition[Join[Take[pi, 14], Characters["..."], Take[pi, pos - {13, 1}], Style[#, Orange] & /@ Take[pi, pos], Take[pi, pos + {5, 4}]], 10], Spacings -> {0, 0}], 40, Background -> Black, FontColor -> White]

Or add some more information:

And now you can know exactly what digit of pi any time of day begins at

Where are you at?


You can enable GPS to track your current location in both Apple Watch and on your phone to find out your location. This makes it very easy to create Lat-Long app geolocation apps that show the width and longitude of your location on the clock (this example shows the coordinates of our headquarters):

In[12]:= Style[Column[{DMSString[Latitude[Here], {1, "NS"}], DMSString[Longitude[Here], {1, "EW"}]}], 30, White, Background -> Black]

I'm not quite sure that the program presented below can be something useful (to prove your location via Skype?). Actually, here is the application Here & Now QR app , which shows your current coordinates and time as a QR code:

In[13]:= BarcodeImage[StringJoin[DMSString[Here], "|", DateString[Now]], "QR"]

Wolfram Language is aware of many things, and one of them is geography . Here is the code that allows you to find the 10 volcanoes closest to you:

In[14]:= v = GeoNearest["Volcano", Here, 10]

If you add a little more code, they will be shown on the map, and then the whole thing can be assembled into the Nearest Volcanoes app :

In[15]:= GeoGraphics[{GeoPath[{Here, #}] & /@ v, GeoMarker[Here], GeoMarker[#, image:volcano-icon] & /@ v}, GeoRange -> 1.5 GeoDistance[Here, First[v]]]

Here is the code for the 3D Topography app , which shows a three-dimensional scaled map within a radius of 10 miles from your location:

In[16]:= ListPlot3D[GeoElevationData[GeoDisk[Here, Quantity[10, "Miles"]]], MeshFunctions -> {#3 &}, Mesh -> 30, Background -> Black, Axes -> False, ViewPoint -> {2, 0, 3}]

Data coming to the device


As soon as we made contact with the Wolfram Cloud, we had the opportunity to use the real-time data contained in the Wolfram Knowledgebase. Among other things, there is data on the current position ( x , y , z , t ) of the International Space Station :

In[17]:= entity:International Space Station (satellite) ["Position"]

Considering my location and using some graphics in Wolfram Language, you can create an ISS-locator ISS Locator app :

In[18]:= Module[{pos, line, rise}, {pos, line, rise} = SatelliteData[entity:International Space Station (satellite), {"Position", "SatelliteLocationLine", "RiseTime"}]; Style[Labeled[GeoGraphics[{{Pink, AbsoluteThickness[3], GeoPath @@ line}, {Red, PointSize[.04], Point[pos]}, {Opacity[.1], Black, GeoVisibleRegion[pos]}}, GeoGridLines -> Automatic, GeoCenter -> pos, GeoRange -> "World", GeoProjection -> "Orthographic", ImageSize -> {272, 340 - 38}], Style[TemplateApply["Next rise: ``", NumberForm[ UnitConvert[DateDifference[Now, rise], "Minutes"], 3]], White, 20]], Background -> Black]]

As another example of using real-time data, you can bring up the Apple code for the Quanting app , which gives out Apple stock prices:

In[19]:= Style[TradingChart[{"AAPL", DatePlus[-90]}, {"Volume", Style["MESASineWave", {RGBColor[1, 1, 1], RGBColor[0.46, 0.62, 0.8200000000000001]}], Style["BollingerBands", RGBColor[1, 1, 1]], Style["DoubleExponentialMovingAverage", RGBColor[1, 0.85, 0.21]]}, PerformanceGoal -> "Speed", Axes -> False, Frame -> False], Background -> Black]

Below is the code for the Market Word Cloud app , which shows the symbolic designation of the company's shares, the size of which is set according to changes in the price for the previous day (today Apple stock prices rose and Google stock prices fell):

In[20]:= WordCloud[With[{c = FinancialData[#, "FractionalChange"]}, Abs[c] -> Style[#, ColorData[{"RedGreenSplit", 0.01 {-1, 1}}, c]]] & /@ {"AAPL", "XOM", "GOOG", "MSFT", "BRK-A", "WFC", "JNJ", "GE", "WMT", "JPM"}, Background -> Black]

Below is the complete currency conversion code based on your current location. Currency Converter app / a>:

In[21]:= With[{home = $GeoLocationCountry["CurrencyUnit"]}, Style[QuantityForm[Grid[{#, "=", CurrencyConvert[#, home]} & /@ Cases[{Quantity[1, "USDollars"], Quantity[1, "Euros"], Quantity[1, "Yen"], Quantity[1, "BritishPounds"]}, Except[home]], Alignment -> Left], "Abbreviation"], White, Background -> Black, 30]]

With Wolfram Language it’s not at all difficult to create a wide variety of applications. Here is the code for the Sunrise / Sunset app , which displays information about the sunset and dawn where you are:

In[22]:= {Sunrise[], Sunset[]}

Setting up a more convenient display for the clock requires a little more code:

In[23]:= With[{sunfmt = Style[DateString[#, {#2, " ", "Hour12Short", ":", "Minute", "AMPMLowerCase"}], 54] &, tfmt = Round[DateDifference[Now, #, {"Hour", "Minute"}], 5] &}, Rasterize@Style[Column[{sunfmt[Sunrise[], "rise"], tfmt[Sunrise[]], sunfmt[Sunset[], "set"], tfmt[Sunset[]]}, Alignment -> Right], FontSize -> 32, Background -> Black, White]]

Wolfram Language contains real-time weather data :

In[24]:= AirTemperatureData[]

Which we can display in the form of beautiful built-in icons:

In[25]:= IconData["AirTemperature", AirTemperatureData[]]

Here is the temperature for the last week:

In[26]:= AirTemperatureData[Here, {Now - Quantity[1, "Weeks"], Now}]

And if you add a little code, we can present it as an application with a graph of temperature changes Temperature History app :

In[27]:= With[{temps = DeleteMissing[AirTemperatureData[Here, {Now - Quantity[1, "Weeks"], Now}]["Values"]]}, QuantityForm[Style[Column[{Grid[{{"Current", Last[temps]},{"High", Max[temps]}, {"Low", Min[temps]}}, Alignment -> {{Right, Left}}], ListLinePlot[temps, ImageSize -> 312, PlotStyle -> None, Filling -> Bottom, FillingStyle -> Automatic, ColorFunction -> Function[{x, y}, Blend[{RGBColor[0.45, 0.72, 0], RGBColor[1, 0.85, 0]}, y]], PlotTheme -> "NoAxes"]}, Alignment -> Right], Background -> Black, 24, White], "Abbreviation"]]

Sometimes the easiest way to get results in Wolfram Language is to simply contact Wolfram | Alpha . Here's what Wolfram | Alpha will show if you ask the system about the time it takes to get a good tan (it determines your current location):

Wolfram|Alpha recognizes your location, knows the current UV index there, and computes how long you could safely stay out in the sun depending on your skin type

And so, it turned out the real-time application, the Sunburn Time app , in which the Wolfram | Alpha is invoked using the Wolfram Language construct (the application issues different times needed to get a good tan depending on skin type).

In[28]:= times = Style[QuantityForm[#, {}], 24, White, FontFamily -> "Source Sans Pro"] & /@ Rest[WolframAlpha["sunburn time", {{"TypicalTimeToSunburn", 1}, "ComputableData"}][[All, 2]]]; In[29]:= Panel[Grid[Transpose[{{image:skintonesI, image:skintonesII, image:skintonesIII, image:skintonesIV, image:skintonesV, image:skintonesVI}, times}], Dividers -> {False, Center}, FrameStyle -> Gray, Spacings -> 5, Alignment -> {Center, Center}], Background -> Black]

Reports and data download


Wolfram Language has access not only to data streams from its sources, but also to private ones; in particular, to the data from Wolfram Data Drop (see the article on Habrahabr " Wolfram Data Drop - new Wolfram Research service ")

As an amateur of collecting and analyzing personal data , I made a databin at Wolfram Data Drop, which tells me the number of unprocessed and unread emails. I created a scheduled task that runs in the cloud and creates a report about my unread messages. Now let's create the SW Email Backlog app , which will send this report on demand and display it on the clock:

Lighter orange is total number of messages; darker orange is unread messages...

Yes, the number of unprocessed and unread messages has recently increased at least in part due to the fact that now some additional time is spent on work on this blog.

Now everywhere you can meet Wolfram Data Drop databins and, of course, you can make your own . From any databin, you can immediately make an application for watches with a panel for displaying information. As, for example, the Company Fridge app , which receives information from a small thermal sensor that is located in a refrigerator at our headquarters (the cyclical nature of the schedule is caused by the compressor, and the peaks correspond to the opening of the refrigerator):

In[30]:= DateListPlot[Databin["4r4-gP4o", -300, "temp"], PlotStyle -> RGBColor[0, 0.501961, 1], Background -> Black, DateTicksFormat -> {"Hour12Short", "AMPMLowerCase"}, FrameStyle -> Directive[Black, FontColor -> White, 18], FrameLabel -> Automatic, TargetUnits -> Quantity[1, "DegreesFahrenheitDifference"], AspectRatio -> 1.11, ImageSize -> 312]["temp"]

Usually databin receives data from any one source or device. However, you can create a databin that receives data from an application that runs on several different devices at once.

As a simple example, let's make an application that simply shows where this application was launched in the world. Here is the complete code for the Data Droplets app, which is ready for uploading :

In[31]:= CloudDeploy[Delayed[With[{db = Databin[DatabinAdd["4rwD7T5G", 0], -20]["GeoLocations"]}, GeoGraphics[{Red, PointSize[.02], MapThread[{Opacity[#], Point[#2]} &, {Subdivide[0.15, 1, Length[db] - 1], db}]}, GeoRange -> All, GeoProjection -> "LambertAzimuthal", Background -> Black, PlotLabel -> Style["Recent Data Droplets", White, 24]]], "PNG"], "WatchApps/DataDroplets"]

This app does two things. First, when it is running, it adds the location of the device on which the application is running to the central databin in Wolfram Data Drop. And secondly, it displays a world map with marks of the last 20 places from which the application was launched:

Data Droplets app on the watch--just touch the screen...

Realizing the app


The main reason to run applications on your watch is to be able to receive information directly from your wrist. However, you can use these applications to work with some external systems, for example, through an API.

As one very simple example, below is the complete code for an application ready for unloading, which sends an application card with a one-mile radius from its position to the application owner, and sends it at the moment the application starts:

In[32]:= CloudDeploy[Delayed[SendMail[GeoGraphics[{Opacity[.4, Red], PointSize[.05], Point[Here]}, GeoRange -> Quantity[1, "Miles"]]]; Style["Sent!", 200], "PNG"], "WatchApps/MailMyLocation", IconRules -> image:maillocationicon]

Email sent by the MailMyLocation app--log where you've been, share your location, remember where you parked...

Applications to create other applications


Until that time, all the applications we talked about were created from fixed code snippets on the Wolfram Language, which were deployed on the Apple Watch. However, the Wolfram Language is a symbolic language, so manipulating the application code is as simple as any other data. This means that using Wolfram Language to create and deploy applications on the fly will be very easy.

Here is a simple example. Let's say we want to make an app for a clock that counts down the days until our next birthday. It would be very inconvenient to enter the date of your birthday right on the clock. But instead, the application can be placed on the phone, where the date of birth is entered, and after that it can create another application for the clock in real time, which will be counted exactly for your date of birth.

Below we will enter the date of birth in the standard for Wolfram Language “ smart field ”, which works with any date formats:

Run the generator app on your phone and enter your birthday...

And as soon as we click the Submit button, this application will run the code on the Wolfram Language in the Wolfram Cloud, which will generate a new application with the date specified by us, and then this application will be deployed and launched on our watch.

...And it deploys the generated app to the watch, ready to run

Below is the complete code that is required to create the Birthday Countdown app , which generates new, customized, applications.

In[33]:= CloudDeploy[FormFunction[{"Birthday" -> "Date"}, (CloudDeploy[Delayed[ExpressionCell[With[{count = Floor[UnitConvert[Mod[# - Today, ="1 yr"], "Day"]] &}, Style[Framed[Pane[QuantityForm[count[#Birthday], "Abbreviation"], {250, 250}, Alignment -> Center], RoundingRadius -> 50, FrameStyle -> Thick], 40, Hue[.52]]], Background -> Black], "PNG"], "WatchApps/BirthdayCountdown", IconRules -> image:cakeicon]; Style["BirthdayCountdown app generated & deployed", Larger, Background -> LightYellow]) &, "PNG"], "WatchApps/CountdownGenerator", IconRules -> image:cakeandgearicon]

And here is the result of the generated application for the countdown to my birthday :

As of this writing, there are 123 days until my next birthday. How many days until your own?

You can make a variety of applications like the ones presented above. Here is an example of an application where you need to make a list of different places, after which an application is created that displays different times for the corresponding places:

Enter a list of cities on your phone, and get an array of clocks for them

You can also use application generation to put yourself in the application. Here is the code for deploying the spawn of other apps, the You Clock app . It allows you to take a picture of yourself using the phone and create an application that uses this picture as a clock:

In[34]:= CloudDeploy[FormFunction[{"image" -> "Image"}, (With[{hand = ImageRotate[ImagePad[ImageResize[#image, 100, Resampling -> "Gaussian"], {{0, 0}, {50, 0}}], -Pi/2]}, CloudDeploy[Delayed[ClockGauge[Now, PlotTheme -> "Minimal", GaugeMarkers -> {hand, hand, None}, Background -> Black, TicksStyle -> White, ImageSize -> 312], "PNG"], "WatchApps/YouClock", IconRules -> "YouClock"]]; Style["YouClock app deployed", 50]) &, "PNG"], "WatchApps/YouClockGenerator", IconRules -> "YCG"]

And here I am as the hands of a clock

In fact, this process can be approached even more generally: you can create applications that other applications generate, and they, in turn, also create their own applications!

More than i expected


When I decided to use Wolfram Language to create applications on the Apple Watch, I did not know how this would happen. Will the entire application deployment cycle for a clock work quite smoothly? Will those applications that are so easy to create using Wolfram Language look good on your watch?

I'm glad to say that everything went much better than I expected. Apple Watch appeared quite recently, so there were some questions about the deployment of applications on them, but they decided very quickly. But it became clear that many good applications for Apple Watch can be created even with a small amount of code in the Wolfram Language (tweet-a-watch-app? See the article on Habrahabr " Wolfram Research opened the Tweet-a-Program service: interesting programs in the Wolfram Language language, the length of which does not exceed 140 characters "). At the same time, I was very impressed with the fact that in less than one day of work, I was able to develop 25 full-fledged applications.

Of course, all this became possible thanks to the entire set of Wolfram Language technologies , which have been developed for almost 30 years. And it is very pleasant to see how well our automation tools work, which allowed us to implement another interesting idea - applications for watches.

It's great to program on the Wolfram Language and observe the results of what happened - as in the case of writing applications for the Apple Watch. But in the end, more important is how comfortable it is for the realization of many different goals and ideas. The code presented here is a good help to understand everything. There are many areas for action. You can create a lot of useful, and just fun applications. It is important that Wolfram Language allows you to create applications for the Apple Watch so easily that it can turn into a daily routine - this is another place where Wolfram Language functionality can be introduced.

Source: https://habr.com/ru/post/257171/


All Articles