Swiftgen: Plist and inline-swift template not working with Arrays

Created on 30 Oct 2019  路  10Comments  路  Source: SwiftGen/SwiftGen

Hello,
I'm trying to use the template plists/inline-swift4.stencil template to generate the content of a plist.

So far the content of the plist is:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Names</key>
    <array>
        <string>Jhon</string>
        <string>Peter</string>
        <string>Nick</string>
    </array>
    <key>Surnames</key>
    <array>
        <string>Smith</string>
        <string>Jhonson</string>
        <string>Williams</string>
    </array>
</dict>
</plist>

And visually it looks:

Screenshot 2019-10-30 at 12 53 11

Then in the .swiftgen.yml I just have somethings as:

.........
plist:
    inputs: Precompile/OriginPlists/
    outputs:
        templateName: inline-swift4
        output: Generated/Plist.swift
.....

When I execute it, it generates wrong data:

internal static let names: [String] = [Jhon, Peter, Nick]
internal static let surnames: [String] = [Smith, Jhonson, Williams]

If you see it misses the quotes in every single element in the array, and in the plist, they are declared as String

Digging into the template I found where the issue "could be", I have created a solution, I tried locally and is working fine, but I don't know if this is breaking something else. Besides I see that the same logic is applied in several templates, so not sure if in these templates is broken as well.

The solution that I applied in the plists/inline-swift4.stencil was:

@@ -55,9 +55,9 @@ import Foundation
     Date(timeIntervalSinceReferenceDate: {{ value.timeIntervalSinceReferenceDate }})
   {% elif metadata.type == "Optional" %}
     nil
-  {% elif metadata.type == "Array" and metadata.element.items %}
-    [{% for itemMetadata in metadata.element.items %}
-      {% call valueBlock value[forloop.counter0] itemMetadata %}
+  {% elif metadata.type == "Array" and value %}
+    [{% for currentValue in value %}
+      {% call valueBlock currentValue metadata.element %}
       {% if not forloop.last %}, {% endif %}
     {% endfor %}]
   {% elif metadata.type == "Dictionary" %}

The new output is:

internal static let names: [String] = ["Jhon", "Peter", "Nick"]
internal static let surnames: [String] = ["Smith", "Jhonson", "Williams"]

馃帀 馃帀 馃帀 馃帀 馃帀 馃帀 馃帀

I didn't create the PR, because I'm not sure if this will break something else or if I need to apply the same logic in more files.

Thanks!

bufix

All 10 comments

Any news?

I think you need to create a PR

Yes sure, I will create it

@fjtrujy I faced the same issue and if would be great if you create PR, I will try to assist it also.

Hello @aminbenarieb I will try to create the PR tomorrow!
Thanks

Pull request created!

https://github.com/SwiftGen/SwiftGen/pull/687

Thanks guys

~@fjtrujy I'm not 100% sure if there's actually an issue...~

~We already have tests for arrays: shopping-list.plist is an array of strings, and info.plist contains an array (of dictionaries) at fabric.Kits. Even then, I've tried generating output with your test of names+surnames, and the current template generates correct code (with quotes).~

~Could you verify what template you're actually using (swiftgen template cat), and what SwiftGen version you're using? Maybe also give SwiftGen 6.2.0 a try.~

Note:
Your proposed fix actually breaks code generation for arrays of mixed types. You need to pass the correct item metadata to the call valueBlock, i.e.:

{% call valueBlock currentValue metadata.element.items[forloop.counter0] %}

Even then, the proposed (fixed) change essentially does the exact same thing as the current template code: they both iterate over an array, and pass along an item + the corresponding item from another array to a function. Our code iterates over metadata items and passes along the corresponding value item, your (fixed) code iterates over values and passes the corresponding metadata item.

Edit:
Disregard what I said above, I was able to reproduce the issue. The proposed fix still needs changes to handle mixed arrays ([Any]).

Hello,
Again I tried to update the fix that I did, but some other unit test are not passing, so it requires further changes.
Honestly, I'm not an expert leading with these templates, this is why I didn't finish the work in my PR.

Thanks

I think this issue can be closed because it has been fixed in #687
Thanks guys!

The issue has been fixed yes, but 6.2.1 hasn't been released yet.
We hope to release it really soon though 馃槃

Was this page helpful?
0 / 5 - 0 ratings

Related issues

razor313 picture razor313  路  6Comments

kacper1703 picture kacper1703  路  3Comments

gereons picture gereons  路  5Comments

drjasonharrison picture drjasonharrison  路  5Comments

marcelofabri picture marcelofabri  路  6Comments