igor-makarov / xcake

:cake: Describe Xcode projects in a human readable format and (re)generate one on demand.
MIT License
632 stars 48 forks source link

Localized resources are not being created correctly #227

Closed samuelsainz closed 1 year ago

samuelsainz commented 2 years ago

Description

I have noticed that for Localized resources as .storyboards, .xib or .plist, the references are not being generated correctly. I looked into the closed issues to see if this has happened to someone before but I didn't find anything.

Expected:

expected

Result with Xcake:

output

The folder structure is the next one:

Resources -- Base.lproj ---- MainInterface.storyboard -- es.lproj ---- MainInterface.strings -- de.lproj ---- MainInterface.strings ....

Which is the folder structure that the Xcode generates when you Localize a storyboard from the interface.

Why is this happening?

The representation of the expected result in the xcodeproj is a PBXVariantGroup. These variant groups are created in Xcake with this method.

When Xcake finds a file that has a parent folder *.lproj it will try to add it to a variant group with the same name of that file. The issue happen when comparing MainInterface.storyboard and MainInterface.strings, since they are different it creates two separated PBXVariantGroup instead of being included in the same one—which also should have the name MainInterface.storyboard.

Expected:

EA1ACF101F59E02400C603F2 /* MainInterface.storyboard */ = {
    isa = PBXVariantGroup;
    children = (
        EA1ACF111F59E02400C603F2 /* Base */,
        B0281D7D21F93A8B004FB23B /* es */,
        B0281E4C21F946CD004FB23B /* de */,
        B0800E9121F97DDF00ABFD6F /* fr */,
        B0DF2EDF21F9939C0063D5CF /* it */,
        B020A2D82284D2A300677E3F /* en-GB */,
        B6A02FD2236C53CC00E37AE8 /* nl */,
        A6600B14256E702800312EEF /* es-MX */,
        A6990549256E705B0091C3C7 /* es-US */,
    );
    name = MainInterface.storyboard;
    sourceTree = "<group>";
};

Result:

D8B4C4E1925A95E8DC0E74AC /* MainInterface.strings */ = {
    isa = PBXVariantGroup;
    children = (
        04950444FAFC6C0F952059B4 /* MainInterface.strings */,
        AB969AF0F0A1B1F4ABFF67CB /* MainInterface.strings */,
        C13D82614D223953A14C7131 /* MainInterface.strings */,
        B7B2F90DEDB577D3AFA62A6A /* MainInterface.strings */,
        DA59504E9DF6F5DC87EEFB77 /* MainInterface.strings */,
        E72594D2629C5AD29D4421BC /* MainInterface.strings */,
        050F1CC7602AA07DC9FCE591 /* MainInterface.strings */,
        DE6974DADAB0A22D6A02E4B3 /* MainInterface.strings */,
    );
    name = MainInterface.strings;
    sourceTree = "<group>";
};
F9A28B7687315B0117993456 /* MainInterface.storyboard */ = {
    isa = PBXVariantGroup;
    children = (
        E6C1F1B113810268366AB784 /* MainInterface.storyboard */,
    );
    name = MainInterface.storyboard;
    sourceTree = "<group>";
};

Another thing that is happening is that the .strings files are being included in PBXBuildFile and PBXResourcesBuildPhase. That doesn't happen when you localize a resource using Xcode.

PR Guidelines

I'm exploring alternatives to make a fix and send a PR, do you have any suggestion on how to solve this?

igor-makarov commented 2 years ago

@samuelsainz thank you for the detailed report! Can you clarify whether this is only a cosmetic issue (folder looks wrong) or does this also result in incorrect build products as a result?

samuelsainz commented 1 year ago

@igor-makarov hey Igor, I'm sorry for the late reply.

We could say it is only a cosmetic issue, since for that specific resource Localization will work anyway. Here I have created a sample project to test that the localization works: https://github.com/samuelsainz/xcake-localized-resources

But in our project we still had an issue with this. Let's consider the next example:

The app target has the next resources added to it in the original project:

If I use xcake, I will get the next:

So we get the error Multiple commands produce Location.strings file.

The workaround was easy—just renaming the storyboard or the strings file fix the issue. Not a blocker for us but more than happy to contribute if you think it is worths to solve it

igor-makarov commented 1 year ago

@samuelsainz I've looked at the sample project you provided, and tried to replicate the scenario you described, the .storyboard and .strings having the same filename.

I've added the files to Xcode and this is the group structure I've gotten:

Screen Shot 2022-10-25 at 19 41 17

The build succeeded.

I recalled that the final folder structure was supposed to be flat, so I was suspicious. I've opened the build product to inspect the results. To my surprise, the folders looked like so:

Screen Shot 2022-10-25 at 19 44 49

There was only one ElaborateName.strings file per language. I've inspected its contents, and it contained only the storyboard localization, and not the other strings.

in other words, Xcode was somehow allowing an incorrect build to happen. I've experimented with deleting various .lproj folders within the built product, and had managed to get it to copy either file. My hunch is that the "Compile Storyboard" build task doesn't have the .strings output files declared on it.

I will be opening a feedback to Apple with this.

TL;DR: Having same-named .storyboard and .strings files is not possible due to the final app bundle structure. Xcake's bug has (ironically) protected you from it, while plain Xcode has a bug in it.

samuelsainz commented 1 year ago

@igor-makarov I see, we will rename the duplicated resources then. Thanks a lot for digging into it Igor!

If you open a feedback to Apple for that please share the link so we can follow up :)

igor-makarov commented 1 year ago

@samuelsainz there isn't a way to share a link in Apple Feedback, but the ID is FB11718625.

igor-makarov commented 1 year ago

Closing this issue.