1

I have a function in Swift 3 that gets metadata from MPMediaItems - in this case Podcasts.

The problem is that for some older Podcasts, when I retrieve a metadata Key instead of getting a String I get an NSTaggedPointerString which is essentially empty for my purposes - I can't compare it to a literal.

Here's an example of what I expect (String):

enter image description here

And here's what is giving me heartburn:

enter image description here

(I know the keys are not the same but that's not the issue)

How can I get the actual String value from the NSTaggedPointerString while still being able to get/use the more common String values that I also get?

Here's my function:

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
}

Another question is this: Why can I print the value of the key correctly, but not use it as a String for comparison?

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

EDIT:

I'm making some small progress but still no solution. I've been tinkering with my code and am now trying this:

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)")
    }
}

It seems so strange that when I can see that myKey contains a value (pic 1) and I can print it, I am not able to remove the Optional() indicator. When I add the ! the value becomes empty and I cannot do a comparison - but I can still print it!! (pic 2)

pic 1 pic 1

pic 2 pic 2

EDIT 2: Finally a solution !

@alDiablo had a good suggestion but only got me part-way. I discovered through more research that part of the problem was a leading Null char "\0" in the returned string. Once I found that out, I could strip it off and do my comparison.

So here is the resulting code to handle the metadata key:

let realString = NSString(string: metadata.key! as! String)  //There is probably a cleaner way to do this too
let sKey = realString.replacingOccurrences(of: "\0", with: "")
if (sKey == "TDS") || (sKey == "TDES"){
        //Success!
}
wayneh
  • 4,393
  • 9
  • 35
  • 70
  • It's an "internal class for NSString", you shouldn't worry about that. If it's empty, then your String is empty. – Larme Apr 02 '17 at 19:12
  • @Larme - Thanks for the response but I don't think you've followed my post. I can clearly print out a value so it's not empty. As well, it yields "" when used by itself. – wayneh Apr 02 '17 at 19:18

1 Answers1

0

Try this:

let realString = NSString(string: nsTaggedPointerString)

alDiablo
  • 969
  • 7
  • 22
  • I'm currently installing Xcode 8.3 and it's taking forever, but I will try your solution later tonight. – wayneh Apr 05 '17 at 23:23
  • OK, I finally got it working! Your suggestion did help, but was not a complete answer. I'm still giving you the bounty points because it did help me get there. I've edited my OP to reflect the final code. Thanks. – wayneh Apr 06 '17 at 18:52
  • Thanks for that, I'll note this point in my book. Will help me later :) – alDiablo Apr 07 '17 at 07:34