NCrusher74 / AudiobookTagger

An audio(book)-centric Swift wrapper combining MP4Foundation with ID3TagEditor for tagging .mp3, .m4b, and .m4a files
Apache License 2.0
9 stars 1 forks source link

trying to create a common value #2

Closed NCrusher74 closed 4 years ago

NCrusher74 commented 4 years ago

Despite the lack of new code in evidence here, I actually spent all day yesterday on this, trying and discarding a bunch of different ways to create a common value for the metadata items I'm dealing with.

Surprisingly, it's ID3TagEditor, rather than MP42Foundation, that is presenting a stumbling block.

With MP42Foundation, the item it reads or writes is identified the same way, by the MP42MetadataKey<whatever>. And you can pretty much access that from anywhere, not simply in the context of a read or write command. So if you wanted to say audiobookAuthor = MP42MetadataKeyArtist that's pretty much all you need to do.

With ID3TagEditor it's a little tougher. There doesn't seem to be a way to access the metadata frames outside the context of a id3TagEditor.read or id3TagEditor.write command, at least not that I can find. Which is making it hard to equate to a simple identifier like audiobookAuthor.

So then I tried to make the common factor a read or write function. But again, I can't seem to find a way to put them on equal footing.

I don't know if I'm going about this the wrong way or what. I just need to find a common way to handle these values so that when I use AudiobookTagger as a package dependency for my apps, I can access the metadata from (or destined for) the tag I want regardless of if I'm dealing with an .mp3 or an .m4b file.

SDGGiesbrecht commented 4 years ago

Did you delete the UI test sources without deleting the product? When I try to build the tests, I get this message:

error: Build input file cannot be found: '[...]/Library/Developer/Xcode/DerivedData/AudiobookTagger-fkklszcwpbwduvbwktwklzkhuyfw/Build/Products/Debug/AudiobookTaggerUITests-Runner.app/Contents/PlugIns/AudiobookTaggerUITests.xctest/Contents/MacOS/AudiobookTaggerUITests' (in target 'AudiobookTaggerUITests' from project 'AudiobookTagger')

NCrusher74 commented 4 years ago

I... don't remember doing that? Let me see what I can do.

SDGGiesbrecht commented 4 years ago

If there are leftovers in DerivedData on your machine, you may have to do Product → Clean Build Folder (⇧⌘K) before you see the same error message I see.

NCrusher74 commented 4 years ago

I removed the product. It's building for me, even after cleaning the build folder.

weird, I really don't remember deleting those. But I can see why I would, I don't really intend for this to have an interface.

NCrusher74 commented 4 years ago

I have to run out the door to a meeting. I'll be back in a couple of hours to try to fix it if that didn't work.

SDGGiesbrecht commented 4 years ago

Is this what you are asking how to do?

// ...
import ID3TagEditor
// ...
enum AudiobookTag {
  // ...
  var id3Tag: FrameName {
    switch self {
    case .BookTitle:
      return .Title
    // ...
    }
  }
}

Any time you see .something (with a leading dot) in isolation, it is really a SomeType.something. It is just that SomeType can be left out if the compiler can already tell from the context what the omitted type has to be.

let x = SomeType.something // ✓
let y = .something // ✗
let z: SomeType = .something // ✓

func useAny(_ argument: Any) {}
useAny(SomeType.something) // ✓
useAny(.something) // ✗
func useSpecific(_ argument: SomeType) {}
useSpecific(.something) // ✓

let a = [SomeType.something: "..."] // ✓
let b = [.something: "..."] // ✗
let c: [SomeType: String] = [.something: "..."] // ✓
SDGGiesbrecht commented 4 years ago

if that didn't work.

It did.

NCrusher74 commented 4 years ago

Okay, yes, that is what I was hoping to do.

So, MP42MetadataItemKey<whatever> is a String, so my audiobookAuthor (or whatever) type will need to conform to both FrameName and String correct? Or will I need to make FrameName and String conform to a whole new protocol before I can consider them to be on equal footing?

(I still haven't actually used custom protocols in practice yet, so I'm sort of guessing here. I've come close to it, but haven't ever actually needed to implement it yet at the end.)

NCrusher74 commented 4 years ago

Nevermind. I was being stupid. Instead of making it a computed property that returns FrameName I can make it a function with a parameter of FrameName that returns a String.