Skip to content
This repository was archived by the owner on Sep 6, 2018. It is now read-only.

Asset Catalog - Named Colors #51

Merged
merged 6 commits into from
Aug 20, 2017
Merged

Asset Catalog - Named Colors #51

merged 6 commits into from
Aug 20, 2017

Conversation

djbe
Copy link
Member

@djbe djbe commented Aug 13, 2017

@djbe djbe changed the title Asset Catalog Colors Asset Catalog - Named Colors Aug 13, 2017
return [
"type": "color",
"name": name,
"value": value
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "value" used here is not the "color value" as in "RGB components". That name could be misleading.
I suggest we structure that context with "type"="color", "name"="basename-of-the-color-without-group-path", "fullname"="name-of-the-color-with-group-path-to-use-in-init" but also red, green blue and alpha keys to match what's output by the ColorParser, in case some people want to use that for anything other than UIColor(name: "full name") — e.g. for generating some some HTML to display the colors or whatnot…

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my comment in the PR, we can't do that for components, colors can be different on a device basis (and other criteria).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I still rename value to something else here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well I think fullname would be better here.

Only problem is, for consistency we should do the same naming for images which would then be breaking 😥

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, so might be better to leave it as is? It's not like value is a bad name, it's the value you eventually pass to UIImage(named: ) or UIColor(named: ), the rest is window dressing.

Copy link
Contributor

@AliSoftware AliSoftware Aug 15, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, could be a misleading context variable name, more misleading for colors that it was for images, but ¯\(ツ)/¯ let's keep it simple.
We could always decide to rename both in a future 6.0, let's not do breaking changes again to the context variables that soon after 5.0 for now 😉

@djbe djbe added this to the 2.1.0 milestone Aug 17, 2017
*/
static let supported = [imageSet]
static let supported = [colorSet, imageSet]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So glad we handled that whitelist, we were ready already 👍

I'm wondering though if we shouldn't have used cases here, i.e.

enum Item: String
  case colorSet
  case imageSet

  static let supported: [Item] = [.colorSet, .imageSet]

That way would would have ensured at compile time that everywhere we have a switch to handle each case we never forget to handle every supported cases and we have an exhaustive switch never forgetting places to add new code with new types being supported.

Of course that would mean handling the case of standard folders without extension (the last case on line 110) outside the switch, like in a separated if block or whatnot, but at least that would add safety provided by the compiler, so…

@@ -104,6 +107,9 @@ extension AssetsCatalogParser {
let type = item.extension ?? ""

switch (type, AssetCatalog.Item.supported.contains(type)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remark about the code below on lin 110:

case ("", _), (_, true):

I think that was meant to handle when the folder either don't have an extension (("", _), or have an extension just because it happens that the group/folder name contains a . in its name, but that has nothing to do with the extensions like .colorset, .iconset or other extensions we can encounter in the asset catalog structure. But that latter case doesn't match the behaviour tested by the second condition (_, true), right?

  • The case (_, true) is matched if AssetCatalog.Item.supported.contains(type) and given than AssetCatalog.Item.supported is an array containing the two extensions previously already tested (colorset and imageset) then those case are guaranteed to already be handled
  • And what we intended to do instead is for cases like a group named "my.icons" where icons would be considered as the extension while that folder should be considered as a standard group. But is that even possible (do asset catalog allow group names with . in them?), and if it's accepted, we should instead test the folder extension against unsupported extensions (and I'm pretty sure that's what was done in the first version introducing that code before we decided to change from a blacklist to a whitelist, overlooking that change in the condition meaning doing that)

It would be nice to take advantage of that PR or do a separate one fix that bug while we're at it (test if . are allowed by Xcode and if they are either test against unsupported or think of a better logic)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, that should have been case ("", _), (_, false):. I think that was a remainder from when we had a blacklist. Xcode allows group names with . in them. Groups with extensions that match an Xcode set extension are considered of that set type.

We have 2 options:

  • maintain a list of all asset catalog types, and have a supported & unsupported list so we can correctly match actual sets <-> groups.
  • ignore all folders with "extensions" in them that we don't support, potentially erroneously thinking that a group is an unsupported set type.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've implemented option 2 for now, but I think we're better off long term using option 1?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the docs (https://developer.apple.com/library/content/documentation/Xcode/Reference/xcode_ref-Asset_Catalog_Format/AssetTypes.html), the group type has no extension, and no periods are allowed in the name of the group.

Following that documentation, option 2 is actually the correct one, and we should ignore groups with periods in them. If, by some quirk in Xcode, periods are allowed, I don't think we should support it unless the documentation changes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👌 good catch in that documentation, I forgot they published that! (Worth putting a link to it as a code comment at the top of the XCAssetsParser if not already done)

Let's not allow periods in group names and follow the documentation, option 2 it is!

XCTDiffContexts(result, expected: "images.plist", sub: .xcassets)
}

func testColors() throws {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a third test for an asset catalog mixing colors + images, generating an heterogeneous context, to ensure that's a working use case too.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in the templates PR. The "colors" catalog now actually (also) contains an image set.

@djbe djbe removed the status: WIP label Aug 19, 2017
The assets parser accepts one (or more) asset catalogs, which it'll parse for `image set`s and folders.
The assets parser accepts one (or more) asset catalogs, which it'll parse for supported set types and groups. We currently support the following types:
- Color Set Type (colorset)
- Group Type
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpicking: feels strange to have the "Group Type" in that list be in the middle of the two others, while it's kind of a special case (no extension). Maybe rather put it either at the very beginning or the very end of that list?

@djbe djbe force-pushed the feature/xcassets-colors branch from 30ee6ca to bafdc45 Compare August 20, 2017 00:31
*/
static let supported = [imageSet]
static let supported: [Item] = [.colorSet, .imageSet]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that we use enum cases then that supported constant is actually no longer needed!

let name = item.lastComponentWithoutExtension
return .image(name: name, value: "\(prefix)\(name)")
case ("", _), (_, true):
default:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid default, prefer case nil: instead. The whole point of having an enum with only the supported cases is also to be sure that if we add a new supported type later the compiler will warn about the places where we forgot to update the code, and default will defeat that purpose 😉

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@djbe djbe force-pushed the feature/xcassets-colors branch from bf6946e to 6d0fe41 Compare August 20, 2017 15:24
@djbe djbe merged commit a8b2ceb into master Aug 20, 2017
@djbe djbe deleted the feature/xcassets-colors branch August 20, 2017 15:29
# for free to subscribe to this conversation on GitHub. Already have an account? #.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants