Я работаю над приложением 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