Приложение Swift macOS, которое отображает обложку альбома iTunes, висит на неквадратных изображениях - PullRequest
0 голосов
/ 29 апреля 2018

Я работаю над приложением MacOS Swift 4, которое использует AppleScript (через AppleScriptObjC) для отображения сведений о дорожке воспроизводимого в данный момент трека iTunes, включая встроенную обложку альбома.

Когда формат файла встроенного обложки альбома - JPG, мое приложение работает отлично, даже если я быстро пропускаю треки в моей библиотеке iTunes. Тем не менее, большая часть моих аудиофайлов содержит PNG-файлы для иллюстрации. Когда изображение представляет собой PNG, приложение иногда отображает иллюстрацию без проблем, но часто оно зависает как стремительный рост использования ЦП и памяти.

Редактировать: Оказалось, что проблема с файлами PNG оказалась проблемой с изображениями обложек альбомов iTunes, которые не являются совершенно квадратными (которые, скорее всего, являются PNG, а не более типичными JPG).

Строка, которая приводит к зависанию, - это строка, которая отображает / изменяет изображение (класс NSImage) в кнопке моего изображения (класс NSButton), связанной с помощью Interface Builder, но я не могу понять, почему JPG работают нормально, в то время как PNGs так часто нет.

Часть MainViewController.swift

class MainViewController: NSViewController {

    @IBOutlet weak var trackTitle: NSTextField!
    @IBOutlet weak var trackArtistAlbum: NSTextField!
    @IBOutlet weak var trackArtButton: NSButton!

    // get current iTunes track info and embedded artwork from array passed from AppleScript function through AppleScriptObjC
    func getCurrentTrackInfo() -> (currentTitle: String, currentArtist: String, currentAlbum: String, currentArtwork: NSImage) {
        let appleScriptFunction = AppleScript.getCurrentTrackInfoAS() as! AppleScriptProtocol
        let infoArray = appleScriptFunction.getCurrentTrackInfoAS()
        let currentTitle = infoArray[0] as! String
        let currentArtist = infoArray[1] as! String
        let currentAlbum = infoArray[2] as! String
        let currentArtworkNSData = (infoArray[3] as! NSAppleEventDescriptor).data as NSData
        let currentArtwork: NSImage
        if NSImage(data: currentArtworkNSData as Data) != nil {
            currentArtwork = NSImage(data: currentArtworkNSData as Data)!
        } else {
            currentArtwork = #imageLiteral(resourceName: "no_artwork_trans")
        }
        return (currentTitle, currentArtist, currentAlbum, currentArtwork)
    }
    func setCurrentTrackInfo() {
        let albumInfo = getCurrentTrackInfo()
        let currentArtistAlbum = albumInfo.currentArtist + " — " + albumInfo.currentAlbum
        trackTitle.stringValue = albumInfo.currentTitle
        trackArtistAlbum.stringValue = currentArtistAlbum
        trackArtButton.image = albumInfo.currentArtwork // loading non-square image into button image at this point causes hang
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        setCurrentTrackInfo()

        DistributedNotificationCenter.default.addObserver(self,
                                                          selector: #selector(iTunesPlayerInfoDidChange(_:)),
                                                          name: Notification.Name("com.apple.iTunes.playerInfo"),
                                                          object: nil)
    }

    @objc func iTunesPlayerInfoDidChange(_: Notification) {
        setCurrentTrackInfo()
    }
}

Часть AppleScriptFunctions.applescript

on getCurrentTrackInfoAS()
    tell application "iTunes"
        try
            set currentTitle to name of current track
            set currentArtist to artist of current track
            set currentAlbum to album of current track
            if count of artwork of current track > 0 then
                set currentArtwork to raw data of front artwork of current track
            else
                set currentArtwork to null
            end if
            set currentTrackInfo to {currentTitle, currentArtist, currentAlbum, currentArtwork} # indexed array, i.e. [0], [1], [2], [3]
            return currentTrackInfo
        end try
    end tell
end getCurrentTrackInfoAS

1 Ответ

0 голосов
/ 30 апреля 2018

После изучения красной сельди изображений PNG, которые перетаскиваются в Swift через мост AppleScriptObjC, некоторые полезные комментарии приводят меня к лучшему пониманию реальной проблемы и довольно простому решению, опубликованному здесь на случай, если кто-нибудь еще столкнется с чем-то подобным.

Исправлено изменение настройки масштабирования изображения кнопки с Proportionally Up or Down на Axes Independent. Вид кнопки, в свою очередь, ограничен тремя сторонами суперпредставления вместе с ограничением 1 to 1 Ratio (сохраняя изображение кнопки с изменяемым размером пользователем идеально квадратным). Ограничение отношения не очень хорошо согласуется с исходной настройкой масштабирования (хотя в Интерфейсном Разработчике не было сообщений о конфликтах).

Документ Apple, касающийся масштабирования изображения: NSImageScaling

Если у кого-то есть лучшее понимание , почему такая настройка масштабирования может привести к чрезмерному использованию процессора / памяти, я хотел бы получить больше комментариев или улучшений к моему ответу (или вопросу).

...