Load app icon from xcassets on OS X - swift

I can't load another app icon into NSImage. I tried to use both asset name and name of the particular file but image is always nil.
let image = NSImage(named: "Alerted")
//let alertedDog = NSImage(named: "Alerted128x128.png")
image?.size = NSSize(width: 128, height: 128)
NSApp.applicationIconImage = image
NSApp.dockTile.display()
Any thoughts?
In packaged file I see only standard AppIcon.icns and there is no Alerted.icns...

There are two types of icons. Additional should be of generic type.

Related

Restrict size of NSTextAttachment image

I am trying to insert an image in UITextView. I have used the following code.
extension TextView {
func add(image: UIImage) {
let attachment = NSTextAttachment()
attachment.image = image
attachment.bounds = CGRect(x: 0, y: 0, width: 40, height: 40)
let attString = NSAttributedString(attachment: attachment)
self.attributedText = attString
}
}
The parent UIViewController calls add(image: UIImage).
In func textViewDidChange(_ textView: UITextView), I save the attributedText in CoreData as a Transforable NSAttributedString. I use
NSAttributedStringTransformer for Transformer
The image's size is 40X40 when added. The image has also the same size when I dismiss the parent UIViewController and present it back. However, if I quit the app and relaunch it, the image is not 40X40. It is larger than then UIScreen's size.
How to set size of the image to be 40X40 even after quitting the app?
By setting attachment bounds, you are not resizing the actual image, just the display bounds. Looks like the attributed string transformer doesn’t serialize the bounds you set. You will have to either resize the image directly, or extend the transformer to add the bounds after deserializing from data.
Edit: I see that NSAttributedStringTransformer is not an Apple-provided transformer. So take a look at the source code and see why the bounds are not serialized properly.

How to get a high resolution app icon for any application on a Mac?

Apple documentation specifies that NSWorkspace icon(forFile:) returns a 32x32 icon, but I'm not sure how to specify a different size.
This is a sample SwiftUI code I'm using to display the icon for XCode:
Image(
nsImage: NSWorkspace.shared.icon(forFile: "/Applications/XCode.app/")
).renderingMode(.original)
One way I found is to use bestRepresentation. You should pass in the dimensions you want the image to be in (e.g. 1024x1024), and it will find you the best representation there is for that size.
if let rep = NSWorkspace.shared.icon(forFile: "/Applications/XCode.app/")
.bestRepresentation(for: NSRect(x: 0, y: 0, width: 1024, height: 1024), context: nil, hints: nil) {
}
Then you can just draw the NSImageRep, or create an NSImage using it:
let image = NSImage(size: rep.size)
image.addRepresentation(rep)

Image Literal - Editor placeholder in source file, cannot make it work

When adding an icon to the assets folder it says "Editor placeholder in source file". Does anyone know the solution?
let logo: UIImageView = {
let l = UIImageView()
l.image = #imageLiteral(resourceName: "128x128")
l.contentMode = .scaleToFill
l.layer.masksToBounds = true
//l.layer.cornerRadius = 20
return l
}()
Just type image literal and it will complete with default icon.
Double click on this icon and it will open the media library right side of it.
then pick the image you want

macOS - Programmatically display an image using NSImageView

Using a Swift app targeting the macOS platform, I am trying to programmatically create an NSImageView object, assign an image to it, and then display it, using:
let imageViewObject = NSImageView();
let img = NSImage(cgImage: winCGImage, size: NSZeroSize);
imageViewObject.image = img
self.window.contentView?.addSubview(imageViewObject)
However, no image is displayed when I run this.
On the debugger, I can see that imageViewObject.image (i.e. img) has a valid image, and I can view it using the eye icon.
What am I missing?
You are creating an image view with a zero frame, first create the image and then the view passing the proper size.
let img = NSImage(cgImage: winCGImage, size: NSZeroSize)
let imageViewObject = NSImageView(frame: NSRect(origin: .zero, size: img.size))
imageViewObject.image = img
Avoid to create views with the default initializer ().

AppleTv / TvOS - Resize TopShelf Images in TVContentItems Saved to ImageURL

I am implementing TopShelf in Apple tvOS. I have downloaded images and assigned to imageURL of TVContentItems. The downloaded images aspect ratio does not fit into the TopShelf Images properly. I have tried to change the size by appending width + height to the image link.
www.mydownloadedimages.com/{width}x{height}
But it didn't work.
Can I do resizing at client end in any other way. In the TVContentItem class I have only have NSURL object. There is no UIImage Object.
Thanks a lot.
Here is Apple's documentation on Image Sizes and shapes
// ~ 2 : 3
// ~ 1 : 1
// ~ 4 : 3
// ~ 16 : 9
// ~ 8 : 3
// ~ 87 : 28
//#property imageShape
//#abstract A TVContentItemImageShape value describing the intended aspect ratio or shape of the image.
//#discussion For Top Shelf purposes: the subset of values which are //valid in this property, for TVContentItems in the topShelfItems property //of the TVTopShelfProvider, depends on the value of the topShelfStyle //property of the TVTopShelfProvider:
TVTopShelfContentStyleInset:
valid: TVContentItemImageShapeExtraWide
TVTopShelfContentStyleSectioned:
valid: TVContentItemImageShapePoster
valid: TVContentItemImageShapeSquare
valid: TVContentItemImageShapeHDTV
When the value of this property is not valid for the Top Shelf style, the system reserves the right to scale the image in any way.
You're right saying that the TVContentItem has no UIImage type property. Since TVContentItem also accepts local file URLs in the imageURL property, a workaround can be:
grabbing the UIImage from internet
creating a new image context with the size of the top shelf image
saving it into the NSCacheDirectory
setting the local image URL as imageURL.
Here are the steps:
Let's create our TVContentItem object:
let identifier = TVContentIdentifier(identifier: "myPicture", container: wrapperID)!
let contentItem = TVContentItem(contentIdentifier: identifier )!
Set the contentItem's imageShape:
contentItem.imageShape = .HDTV
Grab the image from Internet. Actually I did this synchronously, you can also try to use other async methods to get that (NSURLConnection, AFNetworking, etc...):
let data : NSData = NSData(contentsOfURL: NSURL(string: "https://s3-ak.buzzfed.com/static/2014-07/16/9/enhanced/webdr08/edit-14118-1405517808-7.jpg")!)!
Prepare the path where your image will be saved and get your UIImage from the data object:
let filename = "picture-test.jpg"
let paths = NSSearchPathForDirectoriesInDomains(.CachesDirectory, .UserDomainMask, true)
let filepath = paths.first! + "/" + filename
let img : UIImage = UIImage(data: data)!
Assuming you've already set the topShelfStyle property, get the size of the top shelf image with the method TVTopShelfImageSizeForShape. This will be the size of your image context:
let shapeSize : CGSize = TVTopShelfImageSizeForShape(contentItem.imageShape, self.topShelfStyle)
Create your image context of shapeSize size and draw the downloaded image into the context rect. Here you can do all your modifications to the image to adjust it into the desired size. In this example I took a square image from Instagram and I put white letterbox bands on the right and left sides.
UIGraphicsBeginImageContext(shapeSize)
let imageShapeInRect : CGRect = CGRectMake((shapeSize.width-shapeSize.height)/2,0,shapeSize.height,shapeSize.height)
img.drawInRect(imageShapeInRect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
In the end, save this image into your NSCacheDirectory and set the image path as contentItem's imageURL.
UIImageJPEGRepresentation(newImage, 0.8)!.writeToFile(filepath, atomically: true)
contentItem.imageURL = NSURL(fileURLWithPath: filepath)
Complete your TVContentItem with other details (like title, internal link, etc...), run the top shelf extension... et voilà!
I would like to add to Nicola Giancecchi's answer. The Top Shelf extension will run on a non main thread so using methods like UIImageJPEGRepresentation or UIImagePNGRepresentation will sometimes stop the Top Shelf thread printing this in the console:
Program ended with exit code: 0
To fix this you can wrap your code like this:
DispatchQueue.main.sync {
UIImageJPEGRepresentation(newImage, 0.8)!.writeToFile(filepath, atomically: true)
let imageURL = NSURL(fileURLWithPath: filepath)
if #available(tvOSApplicationExtension 11.0, *) {
contentItem.setImageURL(imageURL, forTraits: .userInterfaceStyleLight)
contentItem.setImageURL(imageURL, forTraits: .userInterfaceStyleDark)
} else {
contentItem.imageURL = imageURL
}
}