WatchOS 2 - Transferring image sequences for animation - animation

I'm having trouble converting my app from WatchOS 1 to WatchOS2. I'm programmatically creating a sequence of images on the iPhone for the Watch to play.
I'm putting them in a zip file (using SSZipArchive) in iOS and using transferFile() to send it over to the watch where I unzip it in the Watch Extension delegate to the shared container between the Watch Extension and Watch App, that the Watch App can play the sequence later:
func session(session: WCSession, didReceiveFile file: WCSessionFile)
{
imagesURL = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier("group.com.xxxx.images")
SSZipArchive.unzipFileAtPath(file.fileURL.path, toDestination:imagesURL!.path)
}
I've checked that the shared group is set up correctly, and I can see the image files in the shared directory (imagesURL!.path).
But when I get ready to play the sequence with:
image.setImageNamed("myImages") // myImages0.png, myImages1.png, myImages2.png, etc.
I get the error: Unable to find image named "myImages" on watch
Am I putting the images in the right place?
Am I referring to them correctly in setImageNamed?
Am I missing something else?

The correct answer is to use the animatedImageNamed:duration: method of UIImage if you have a series of image files already created, then set that animation using the setImage: method.
So the correction to my original code is a simple one-line change:
image.setImage( UIImage.animatedImageNamed("myImages", 3) ) // myImages0.png, myImages1.png, myImages2.png, etc.
(assuming the duration is 3 seconds)

Why setImageNamed: fails
According to the WKInterfaceImage documentation, setImageNamed loads the image from the watch app bundle.
Whenever possible, place image resources in an asset catalog in your Watch app bundle (not in your WatchKit extension’s bundle). Placing them in the Watch app bundle lets you use the setImageNamed: method to load the animated image at runtime, which simplifies the loading process.
To load an animated image sequence from images in your Watch app bundle, you must name your image resources appropriately and use the setImageNamed: method of this class.
This is why setImageNamed: can't find the images, as they are not a static resource bundled with the watch app.
How to load a dynamic animated image
Since your animation images are dynamic, this is handled by the watch app extension.
For animations you generate dynamically, use the animatedImageWithImages:duration: method of UIImage to assemble your animation in your WatchKit extension, and then set that animation using the setImage: method.
You need to first use animatedImageWithImages:duration: to assemble the dynamic animated image you transferred, then set that animation using setImage:
let animatedImages = UIImage.animatedImageWithImages(images, duration: 3)
image.setImage(animatedImages)
Update:
As Scotty pointed out, the better solution is to use animatedImageNamed:duration: to avoid needing to create the array of images!

Related

Swift 4 How to force Xcode to render vector images?

I am writing the app using latest Swift 4.1.2 and Xcode 9.4.1 for iOS 11.4. So I want to use vector images in my app in PDF format. I made the simple app which showing the problem, please, look:
This app only show only one image, but if you rotate the screen, rendering happens and picture becomes beautiful.
So the question is: how to force Xcode render vector images in Main.storyboard without touching the code? So app upload already rendered images?
Go to -> Images.xcassets and select the image. From the attributes inspector, make sure that preserve vector data is checked as following:
I hope it solves your problem.
Xcode 9 changes situation for vector data by allowing you to choose to treat the image as a vector at runtime. This means the image can smoothly scale to arbitrary sizes. The only change you need to make is to tick Preserve Vector Data for the PDF image in the asset catalog.

What does Auto Scaling do in Xcode 10 xcasset image properties

Found new option on xcasset catalogue image property in Xcode 10 called "Auto Scaling".
What does this property do?
Is it in any way related to Resizing: "Preserve Vector Data" when using PDF vector assets?
It looks like this may only be used by WatchOS.
From https://developer.apple.com/documentation/watchkit/supporting_multiple_screen_sizes?language=objc
Alternatively, in watchOS 5 and later, you can provide scalable PDF assets. Add a PDF as a 2x image asset, then set its Auto Scaling attribute to Automatic. When you load the PDF, the system scales the image based on the current device’s screen size as listed in the table. This allows you to provide a single asset for all four screen sizes.
I'm not sure if this works on iOS as well. I was unable to find any mention of auto scaling outside of this WatchKit documentation.

Storing FileURLs

I have an application that allows the user to load and display images. In the QML front end I am using a fileDialog to get the file URLs which are then loaded using an image loader in C++.
The issue I have at the moment is that if you want to load multiple images you have to load them all at once because once the fileURLs changes, the old URLs are lost.
What is the best way to go about storing the URLs so that I can keep the images displayed?
solution 1:
C++ side, Use a QStringList or a QVector to store paths and load Images from it. Qml side, each time you get new URL push it back to your QStringList.
solution 2:
Declare a qml array (property var array:[]) and store in it the new urls, load images from this list.

Why don't images used in xibs show up in app wide searches

I am in the process of going through a large project and removing unused image assets. I had been using cmd+shift+f to perform a project wide search for given image names. I'd assumed this was working until I realized that if I set an imageview to display an image in interface builder that image reference was not showing up in my search.
Why doesn't the app wide search look for a value within an xib file?
Below is an image in a sample project which recreates the issue. I'm assigning img2 in the xib, but as you can see in the search results img2.png is not found.

How to display pictures in the project resource?

I have a set of small icons and hope to display them in my application when certain condition occurs, for example on sunny day, I display the sunny icon.
I can add the jpg files in the picture, and they seem to be uploaded to phone when I deploy the app. However, I don't know how to access these jpgs in my program.
Could someone help? Thanks a lot!
Check this post about content and resources: http://www.windowsphonegeek.com/tips/wp7-working-with-images-content-vs-resource-build-action
To summarize: You should mark your images with a Build Action of Content or Resource, preferably Content. Now you can reference the Content from your Xaml or in code.
If the Build Action for your image resources is set to Content, then you just specify the Source property for the Image control to the relative path to your images:
this._image.Source = new BitmapImage(
new Uri("/Images/myImage.jpg", UriKind.Relative"));
You can display pictures using the Image element:
<Image Source="/MyImage.png" Visibility="Visible"/>
If you want to switch images according to conditions then you can create multiple images and change each of their Visibility states - or (more preferable) you can create a single image element and change its Source.
Quite how you do this depends on whether you are using databinding or working directly with the UIElements in code behind.

Resources