获取 NSTaggedPointerString 但期待 String - 如何在 Swift 3 中解决?

Getting NSTaggedPointerString but expecting String - how to resolve in Swift 3?

我在 Swift 3 中有一个函数可以从 MPMediaItems - 在本例中是 Podcasts 获取元数据。

问题是,对于一些较旧的 Podcast,当我检索元数据 Key 而不是获取 String 时,我得到的是 NSTaggedPointerString 对于我的目的来说它基本上是空的 - 我无法将它与文字进行比较。

这是我期望的示例(字符串):

这就是让我胃灼热的原因:

(我知道密钥不一样,但这不是问题)

如何从 NSTaggedPointerString 获取实际的字符串值,同时仍然能够get/use我也获取的更常见的字符串值?

这是我的函数:

func getMeta(_ item: MPMediaItem)->String{
    print("")
    print("--------- GETMETA ---------")
    let url = item.value(forProperty:MPMediaItemPropertyAssetURL) as? NSURL
    let asset = AVURLAsset(url: url as! URL, options: nil)

    var sTDES: String = ""
    var sUSLT: String = ""
    var sCOMM: String = ""
    var sTIT3: String = ""
    var sFinal: String = ""

    for metadata in asset.metadata{
        print("sKey:\(metadata.key)")
        print("stringValue:\(metadata.stringValue)")
        if let sKey = metadata.key{

            // All of these comparisons fail if the Key is NSTaggedPointerString
            if (sKey as! String == "TDS") || (sKey as! String == "TDES"){
                if let xtdes = metadata.stringValue{
                    sTDES = xtdes
                }
            }else if (sKey as! String == "COM") || (sKey as! String == "COMM"){
                if let xcomm = metadata.stringValue{
                    sCOMM = xcomm
                }
            }else if (sKey as! String == "USLT"){
                if let xuslt = metadata.stringValue{
                    sUSLT = xuslt
                }
            }else if (sKey as! String == "TIT3") || (sKey as! String == "TT3"){
                if let xtit3 = metadata.stringValue{
                    sTIT3 = xtit3
                }
            }
        }
    }
    //Use the preferred value if available
    if sTDES != ""{
        sFinal = sTDES
    }else if sCOMM != ""{
        sFinal = sCOMM
    }else if sUSLT != ""{
        sFinal = sUSLT
    }else if sTIT3 != ""{
        sFinal = sTIT3
    }else{
        sFinal = " "
    }
    print("sFinal 1:\(sFinal)")

    return sFinal
}

还有一个问题是:为什么我可以正确的打印key的值,但是不能把它当成String来比较?

//This prints correctly
print("** key string:\(metadata.key!)")
// this yields myKey = ""
myKey = metadata.key as! String

编辑:

我正在取得一些小进展,但仍然没有解决方案。我一直在修改我的代码,现在正在尝试:

let metaArray = asset.metadata(forFormat: "org.id3")
for metadata in metaArray{
    print("** metadata key:\(metadata.key!)")
    let myKey = String(describing: metadata.key!) // The ! results in empty value, while keeping it results in Optional
    print("** myKey:\(myKey)")
    if myKey == "TDS"{
        print("value:\(metadata.stringValue)")
    }
}

当我看到 myKey 包含一个值(图 1)并且我可以打印它时,我无法删除 Optional() 指示器,这似乎很奇怪。当我添加 ! 时,该值变为空,我无法进行比较 - 但我仍然可以打印它!! (图 2)

图1

图2

编辑 2: 终于有解决方案了!

@alDiablo 有一个很好的建议,但只让我半途而废。通过更多研究,我发现部分问题是返回字符串中的 leading Null char "[=18=]" 。一旦我发现了这一点,我就可以将其剥离并进行比较。

所以这里是处理元数据键的结果代码:

let realString = NSString(string: metadata.key! as! String)  //There is probably a cleaner way to do this too
let sKey = realString.replacingOccurrences(of: "[=14=]", with: "")
if (sKey == "TDS") || (sKey == "TDES"){
        //Success!
}

试试这个:

let realString = NSString(string: nsTaggedPointerString)