chore: move files around
This commit is contained in:
74
src/Data - Android/Apk+Icon.swift
Normal file
74
src/Data - Android/Apk+Icon.swift
Normal file
@@ -0,0 +1,74 @@
|
||||
import Foundation
|
||||
import AndroidXML
|
||||
|
||||
extension MetaInfo {
|
||||
/// Read `AndroidManifest.xml` but only extract `appIcon`.
|
||||
func readApk_Icon() -> Apk_Icon? {
|
||||
assert(type == .APK)
|
||||
var apk = Apk(self)
|
||||
return Apk_Icon(&apk)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Apk_Icon
|
||||
|
||||
/// Representation of `AndroidManifest.xml` (containing only the icon extractor).
|
||||
/// Seperate from main class because everything else is not needed for `ThumbnailProvider`
|
||||
struct Apk_Icon {
|
||||
let path: String
|
||||
let data: Data
|
||||
|
||||
init?(_ apk: inout Apk, iconRef: String? = nil) {
|
||||
if apk.isApkm, let iconData = apk.mainZip.unzipFile("icon.png") {
|
||||
path = "icon.png"
|
||||
data = iconData
|
||||
return
|
||||
}
|
||||
|
||||
guard let manifest = apk.manifest else {
|
||||
return nil
|
||||
}
|
||||
|
||||
var ref = iconRef
|
||||
// no need to parse xml if reference already supplied
|
||||
if ref == nil {
|
||||
if let xml = try? AndroidXML.init(data: manifest) {
|
||||
let parser = xml.parseXml()
|
||||
try? parser.iterElements({ startTag, attributes in
|
||||
if startTag == "application" {
|
||||
ref = try? attributes.get("android:icon")?.resolve(parser.stringPool)
|
||||
}
|
||||
}) {_ in}
|
||||
} else {
|
||||
// fallback to xml-string parser
|
||||
ref = ApkXmlIconParser().run(manifest)
|
||||
}
|
||||
}
|
||||
|
||||
guard let img = apk.resolveIcon(&ref) else {
|
||||
return nil
|
||||
}
|
||||
path = ref!
|
||||
data = img
|
||||
}
|
||||
}
|
||||
|
||||
/// Shorter form of `ApkXmlManifestParser` to only exctract the icon reference (used for Thumbnail Provider)
|
||||
private class ApkXmlIconParser: NSObject, XMLParserDelegate {
|
||||
var result: String? = nil
|
||||
|
||||
func run(_ data: Data) -> String? {
|
||||
let parser = XMLParser(data: data)
|
||||
parser.delegate = self
|
||||
parser.parse()
|
||||
return result
|
||||
}
|
||||
|
||||
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attrs: [String : String] = [:]) {
|
||||
if elementName == "application" {
|
||||
result = attrs["android:icon"]
|
||||
parser.abortParsing()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user