MPMediaItemArtwork init(image:) deprecated in iOS 10.0
Asked Answered
F

4

16

Apple has deprecated init(image:) method in MPMediaItemArtwork in iOS 10. What is the new alternative.

the class shows interface shows method below to be available in the new OS version

public init(boundsSize: CGSize, requestHandler: @escaping (CGSize) -> UIImage)

Anyone know how to use it?

Also question 2, part of the previous question: Does showing now playing metadata on the lock-screen and control-center using MPNowPlayingInfoCenter work in the simulator?

Faustina answered 16/12, 2016 at 19:43 Comment(0)
F
39

You can use the following code:

let image = UIImage(named: "logo")!
let artwork = MPMediaItemArtwork.init(boundsSize: image.size, requestHandler: { (size) -> UIImage in
        return image
})

And, yes, "now playing" metadata shows on the control center in the simulator.

Fenn answered 20/12, 2016 at 17:58 Comment(4)
Can you shed some light over the "why" and "how" (the hell...) this MPMediaItemArtwork initializer is used? what is expected from this block? to return an UIImage at the provided size? I'm searching the web and cannot get reasonable documentation on this.Hallee
@MottiShneor Various sizes of images are needed -- control center, lock screen, expanded control center, iPhone, iPad. If your media has artwork of varying sizes, then you can return the appropriate media when iOS requests it.Kaluga
But you return the same image again and again, regardless of the size? will the image be resized to fit? is this at all acceptable?Hallee
@MottiShneor - according to the documentation, "The request handler returns the an image in the newly requested size. The requested size must be less than the boundsSize parameter" - so this implementation is incorrect. image should be either resized to the requested size before returning, or created via the resizableImage method.Gurgitation
D
10

I was wondering the same and ended up finding Apple's explanation for this.

They say we shouldn't do any expensive resizing operations on the image when handler is requested, but instead simply return the closely matching image out of ones already available to you.

The following WWDC 2017 video is where they mention it. It's about tvOS, but at least we get some insight. Starts at 07:20: https://developer.apple.com/videos/play/wwdc2017/251/?time=440

Doran answered 9/7, 2018 at 12:44 Comment(0)
B
4

I saw this just now and I'm confused too, but I guess this is the right way:

self.remoteArtwork = [[MPMediaItemArtwork alloc] initWithBoundsSize:CGSizeMake(600, 600) requestHandler:^UIImage * _Nonnull(CGSize size) {

    UIImage *lockScreenArtworkApp = [UIImage imageNamed:@"lockScreenLogo"];

    return [self.manager resizeImageWithImage:lockScreenArtworkApp scaledToSize:size];        
}];

The method - in my case in a singleton "Manager"-Class

- (UIImage *)resizeImageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
    //UIGraphicsBeginImageContext(newSize);
    // In next line, pass 0.0 to use the current device's pixel scaling factor (and thus account for Retina resolution).
    // Pass 1.0 to force exact pixel size.
    UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
    [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}
Bacon answered 18/12, 2017 at 18:2 Comment(3)
This answer isn't really swift, and why have you hardcoded 600x600 for bounds size?Orthodontist
i don´t like swiftBacon
This is not recommended. Apple says so in the video that @Doran linked in another answer.Westphalia
Z
1

Minimum code:

MPMediaItemArtwork(boundsSize: image.size) { _ in image }
Zeppelin answered 15/3, 2019 at 3:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.