Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS ListView does not accept dictionaries via blocks #3149

Open
1 of 8 tasks
ewpatton opened this issue Mar 21, 2024 · 3 comments
Open
1 of 8 tasks

iOS ListView does not accept dictionaries via blocks #3149

ewpatton opened this issue Mar 21, 2024 · 3 comments

Comments

@ewpatton
Copy link
Member

Describe the bug

From the forum: Setting complex data for the list items works via the designer, but adding the result of CreateElement to a ListView in the blocks causes the element to appear as a JSON dictionary instead.

Affects

  • Designer
  • Blocks editor
  • Projects Explorer
  • Companion
  • Compiled apps
  • Buildserver
  • Debugging
  • Other... (please describe)

Expected behavior

Adding an element from the blocks should have the same effect as setting the data via the ListData property in the designer.

Steps to reproduce

  1. Create a project with a ListView
  2. Connect the iOS companion
  3. Set the ListView's Elements property to be a list of elements created with CreateElement.
  4. Observe error
@patryk84a
Copy link
Contributor

I've looked through the code and I don't see a reason why it doesn't work. It seems to me that the dictionary is not correctly recognized in the object. Is it possible?

@ewpatton
Copy link
Member Author

ewpatton commented Apr 6, 2024

Not sure. We will probably need to step through the code to understand why that particular path isn't taken.

@patryk84a
Copy link
Contributor

The ListData function that is called when we set dictionary data in the designer works correctly. So the _listData variable has a valid dictionary which is loaded into the view using _view.reloadData(). So everything that happens after calling _view.reloadData() works correctly. So in my opinion the problem is somewhere in the function that processes the input data, for dictionaries it is the Elements function.

This is the part of the code responsible for processing the input data, placing it in the appropriate variable and loading it into the view. If _listData had a valid dictionary, using _view.reloadData() should load the correct data into the view, just like ListData does. But it's not like that.

set(elements) {
      _elements = []
      _listData = []
      guard !elements.isEmpty else {
        _view.reloadData()
        return
      }
      if elements.first is YailDictionary {
        for item in elements {
          if let row = item as? YailDictionary {
            if let rowDict = row as? [String:String] {
              _listData.append(rowDict)
            }
          } else if let row = item as? String {
            _listData.append(["Text1": row, "Text2": "", "Image": ""])
          } else {
            // Hmm...
          }
        }
      } else {
        _elements = elements.toStringArray()
      }
      let rows = max(_elements.count, _listData.count)
      _automaticHeightConstraint.constant = rows == 0 ? kDefaultTableCellHeight : kDefaultTableCellHeight * CGFloat(rows)
      if let searchBar = _view.tableHeaderView as? UISearchBar {
        self.searchBar(searchBar, textDidChange: searchBar.text ?? "")
      } else {
        _view.reloadData()
      }
    }

So let's dig deeper into the code above:

if elements.first is YailDictionary {
        for item in elements {
          if let row = item as? YailDictionary {
            if let rowDict = row as? [String:String] {
              _listData.append(rowDict)
            }
          } else if let row = item as? String {
            _listData.append(["Text1": row, "Text2": "", "Image": ""])
          } else {
            // Hmm...
          }
        }
      } else {
        _elements = elements.toStringArray()
      }

It seems to me that this condition is not met, even though the data is loaded as a dictionary, both using the CreateElement function and using dictionary blocks to create the appropriate dictionary structure.

if elements.first is YailDictionary {

So this code is executed and the data is loaded as a string:

_elements = elements.toStringArray()

I don't see any error in the above code.

This is a screenshot from an iPhone showing the bug discussed in this report. Why is the dictionary represented by {key = value} and not {key : value} ?

listviewios

Does the dictionary in iOS have this format, or is it the result of this command:

elements.toStringArray()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants