Forum Archive

Problems with ios15

frankL

Is anyone having problems with previously working pythonista scripts after upgrading iPhone to ios15?

frankL

Specifically, it appear that the tableview delegate is not working.

cvp

@frankL It is weird. I have TableView scripts with delegate and I don't see any problem with IOS 15.1

Did you remark the delegate is not called? Which one? I only use tableview_did_select and it works

frankL

This is a simple version of what I'm trying to run:
```
import ui

def show_list_dialog(items=None, args, kwargs):
items = items or []
tbl = ui.TableView(
*kwargs)
tbl.data_source = ui.ListDataSource(items)
my_sel = {'value': None}
class MyTableViewDelegate (object):
def tableview_did_select(self, tableview, section, row):
my_sel['value'] = tableview.data_source.items[row]
tableview.close()
tbl.delegate = MyTableViewDelegate()
tbl.present(style='sheet')
tbl.wait_modal()
return my_sel['value']

w, h = ui.get_screen_size()
view = ui.View(name="Frank's Library", bg_color='lightblue', frame=(0, 0, w, h))

def select_author(sender):
author_unique = ['Baldacci,David', 'Barr,Nevada', 'Bartol,Amy', 'Bernt,Eric', 'Brandt,Kylie', 'Bruni,Riccardo', 'Bryndza,Robert', 'Burke,James Lee', 'Burton,Mary', 'Butcher,Jim', 'Carlson,Tucker', 'Carrol,Sean', 'Case,Andrew', 'Chernov,Ron', 'Clayton,MegWaite', 'Coben,Harlan', 'Cole,Bobby', 'Connelly,Michael', 'Cornwell,Bernard', 'Cornwell,Patricia', 'Cowie,Amber', 'Crombie,Deborah', 'Crosby,Ellen', 'Cross,Katie', 'Cussler,Clive', 'Delaney,Matthew B.J.', 'Dilts,Tyler', 'Dorsey,Tim']
f = (0, 0, 400, 300)
selected_author = show_list_dialog(author_unique, frame=f, name='Select an Author')
author_result.text = str(selected_author)
return

author_button = ui.Button(title='Author', frame=(10,5,350,100), border_color='black', border_width=2, background_color='#EAECEE', action=select_author, font=('Arial Rounded MT Bold',18))
author_button.width=70
author_button.height=40
view.add_subview(author_button)

global author_result
author_entry=''
author_result = ui.TextView(name='author',frame=(100,5,250,40), border_color='black', border_width=3, text=author_entry, font=('Arial Rounded MT Bold',16))
view.add_subview(author_result)

nav_view = ui.NavigationView(view)
nav_view.present('sheet')```

JonB

Are you getting and error? Or the delegate just doesn't run?

cvp

@frankL I don't understand why you set these 4 lines in the delegate function..
Moving them works

def show_list_dialog(items=None, *args, **kwargs):
    items = items or []
    tbl = ui.TableView(**kwargs)
    tbl.data_source = ui.ListDataSource(items)
    my_sel = {'value': None}
    class MyTableViewDelegate (object):
        def tableview_did_select(self, tableview, section, row):
            my_sel['value'] = tableview.data_source.items[row]
            tableview.close()
            #tbl.delegate = MyTableViewDelegate()
            #tbl.present(style='sheet')
            #tbl.wait_modal()
            #return my_sel['value']
    tbl.delegate = MyTableViewDelegate()
    tbl.present(style='sheet')
    tbl.wait_modal()
    return my_sel['value']
frankL

I don't get an error. It appears that the delegate just doesn't run. I removed those lines and it still doesn't work. I put a print statement into the def tableview_did_select functionn and it doesn't get executed.
What is strange is that this same function in several other scripts also stopped working. I checked them after this script stopped working and none of them work now. That's why I thought it might have something to do with ios15. I had just upgraded to ios15 the previous night.

cvp

@frankL said

I removed those lines and it still doesn't work

Ok, you removed lines I commented but did you add the 3 lines I added (exactly the same but left indented twice)

cvp

@frankL said

What is strange is that this same function in several other scripts also stopped working

If you import the same module in several scripts and if you modified (erroneously 😢) this module, it is normal that you could get the same error in these scripts.

frankL

I added those three lines and now it prints the correct selection from within def tableview_did_select but it apparently returns 'none' which is what gets populated into the TextView field. Here is the exact script:

import ui
#
def show_list_dialog(items=None, *args, **kwargs):
    items = items or []
    tbl = ui.TableView(**kwargs)
    tbl.data_source = ui.ListDataSource(items)
    my_sel = {'value': None}
    class MyTableViewDelegate (object):
        def tableview_did_select(self, tableview, section, row):
            my_sel['value'] = tableview.data_source.items[row]
            tableview.close()
            print('my_sel',my_sel['value'])
    tbl.delegate = MyTableViewDelegate()
    tbl.present(style='sheet')
    tbl.wait_modal()
    return my_sel['value']
#
w, h = ui.get_screen_size()
view = ui.View(name="Frank's Library", bg_color='lightblue', frame=(0, 0, w, h))

def select_author(sender):
    author_unique = ['Baldacci,David', 'Barr,Nevada', 'Bartol,Amy', 'Bernt,Eric', 'Brandt,Kylie', 'Bruni,Riccardo', 'Bryndza,Robert', 'Burke,James Lee', 'Burton,Mary', 'Butcher,Jim', 'Carlson,Tucker', 'Carrol,Sean', 'Case,Andrew', 'Chernov,Ron', 'Clayton,MegWaite', 'Coben,Harlan', 'Cole,Bobby', 'Connelly,Michael', 'Cornwell,Bernard', 'Cornwell,Patricia', 'Cowie,Amber', 'Crombie,Deborah', 'Crosby,Ellen', 'Cross,Katie', 'Cussler,Clive', 'Delaney,Matthew B.J.', 'Dilts,Tyler', 'Dorsey,Tim']
    f = (0, 0, 400, 300)
    selected_author = show_list_dialog(author_unique, frame=f, name='Select an Author')
    author_result.text = str(selected_author)
    return

author_button = ui.Button(title='Author', frame=(10,5,350,100), border_color='black', border_width=2, background_color='#EAECEE', action=select_author, font=('Arial Rounded MT Bold',18))
author_button.width=70
author_button.height=40
view.add_subview(author_button)
#
global author_result
author_entry=''
author_result = ui.TextView(name='author',frame=(100,5,250,40), border_color='black', border_width=3, text=author_entry, font=('Arial Rounded MT Bold',16))
view.add_subview(author_result)

nav_view = ui.NavigationView(view)
nav_view.present('sheet')
frankL

BTW the ios version is 15.1.1 on iPhone 12

cvp

@frankL For me, tapping Author, selecting one, fills the TextView and prints correctly (on a IPad 15.1) Remark that 15.1.1 is not yet for iPad

frankL

I get that same thing in the console but it doesn't populate the TextView field. It doesn't appear to be passing the value of my_sel['value'] so I put the assignment line into the def tableview_did_select function and it works. This seems like a real kluge! Beware ios15.1.1

def show_list_dialog(items=None, *args, **kwargs):
    items = items or []
    tbl = ui.TableView(**kwargs)
    tbl.data_source = ui.ListDataSource(items)
    my_sel = {'value': None}
    class MyTableViewDelegate (object):
        def tableview_did_select(self, tableview, section, row):
            my_sel['value'] = tableview.data_source.items[row]
            tableview.close()
            print('my_sel',my_sel['value'])
            author_result.text = my_sel['value']
    tbl.delegate = MyTableViewDelegate()
    tbl.present(style='sheet')
    tbl.wait_modal()
    return my_sel['value']
cvp

@frankL why do you pass via this my_sel['value'] and not via TableView.selected_row?
Check here-under which lines are commented to show they are unused

    #my_sel = {'value': None}
    class MyTableViewDelegate (object):
        def tableview_did_select(self, tableview, section, row):
            #my_sel['value'] = tableview.data_source.items[row]
            tableview.close()
            #print('my_sel',my_sel['value'])
            #author_result.text = my_sel['value']
    tbl.delegate = MyTableViewDelegate()
    tbl.present(style='sheet')
    tbl.wait_modal()
    return tbl.data_source.items[tbl.selected_row[1]]
    #return my_sel['value']
frankL

I did that and now it returns the first item in the list (''Baldacci,David') regardless of which item is selected. Where is "selected_row" defined?

cvp

@frankL said

Where is "selected_row" defined?

Standard TableView process, see doc.
For me, it works, even by selecting another row than 1st one.
Sure, you did copy exactly?
It is like you did type:

    return tbl.data_source.items[tbl.selected_row[0]]

selected_row[0] is the section, here 0 and items[0] is Baldacci

frankL

I did have it as return tbl.data_source.items[tbl.selected_row[1]] but I changed it to return tbl.data_source.items[tbl.selected_row[0]] and it still just returns the first list item ''Baldacci,David'. This is baffling.

cvp

@frankL said

I changed it to return tbl.data_source.items[tbl.selected_row[0]]

Please, don't do that, let [1] and let us try to find why you return always the 1st element

Please post your full code, perhaps an indentation error in what you modified

But one more time, you recreate a new TableView at each tap on the author button

cvp

@frankL please try this one, shorter, without recreating each time thé TableView

import ui
#
class MyTableViewDelegate (object):
  def tableview_did_select(self, tableview, section, row):
    author_result.text = tbl.data_source.items[row]
    tableview.close()

w, h = ui.get_screen_size()
view = ui.View(name="Frank's Library", bg_color='lightblue', frame=(0, 0, w, h))

author_unique = ['Baldacci,David', 'Barr,Nevada', 'Bartol,Amy', 'Bernt,Eric', 'Brandt,Kylie', 'Bruni,Riccardo', 'Bryndza,Robert', 'Burke,James Lee', 'Burton,Mary', 'Butcher,Jim', 'Carlson,Tucker', 'Carrol,Sean', 'Case,Andrew', 'Chernov,Ron', 'Clayton,MegWaite', 'Coben,Harlan', 'Cole,Bobby', 'Connelly,Michael', 'Cornwell,Bernard', 'Cornwell,Patricia', 'Cowie,Amber', 'Crombie,Deborah', 'Crosby,Ellen', 'Cross,Katie', 'Cussler,Clive', 'Delaney,Matthew B.J.', 'Dilts,Tyler', 'Dorsey,Tim']
tbl = ui.TableView()
tbl.name='Select an Author'
tbl.frame = (0, 0, 400, 300)
tbl.data_source = ui.ListDataSource(author_unique)
tbl.delegate = MyTableViewDelegate()

def select_author(sender):
    tbl.present(style='sheet')
    tbl.wait_modal()
    return

author_button = ui.Button(title='Author', frame=(10,5,350,100), border_color='black', border_width=2, background_color='#EAECEE', action=select_author, font=('Arial Rounded MT Bold',18))
author_button.width=70
author_button.height=40
view.add_subview(author_button)
#
author_entry=''
author_result = ui.TextView(name='author',frame=(100,5,250,40), border_color='black', border_width=3, text=author_entry, font=('Arial Rounded MT Bold',16))
view.add_subview(author_result)

nav_view = ui.NavigationView(view)
nav_view.present('sheet')
JonB

@cvp inside your delegate it should be tableview, not tbl.

cvp

@JonB yes, you're right, but tbl is also known, I guess, because it works

JonB

If this code was indeed working before, that suggests something changed with wait_modal. As a check:

import ui
#
def show_list_dialog(items=None, *args, **kwargs):
    items = items or []
    tbl = ui.TableView(**kwargs)
    tbl.data_source = ui.ListDataSource(items)
    my_sel = {'value': None}
    class MyTableViewDelegate (object):
        def tableview_did_select(self, tableview, section, row):
            print('items:', tableview.data_source.items)
            print('section, row:', section, row)
            my_sel['value'] = tableview.data_source.items[row]
            tableview.close()
            print('in delegate: my_sel',my_sel['value'])
    tbl.delegate = MyTableViewDelegate()
    tbl.present(style='sheet')
    tbl.wait_modal()
    print('after wait: ', my_sel['value'])
    return my_sel['value']
#
w, h = ui.get_screen_size()
view = ui.View(name="Frank's Library", bg_color='lightblue', frame=(0, 0, w, h))

def select_author(sender):
    author_unique = ['Baldacci,David', 'Barr,Nevada', 'Bartol,Amy', 'Bernt,Eric', 'Brandt,Kylie', 'Bruni,Riccardo', 'Bryndza,Robert', 'Burke,James Lee', 'Burton,Mary', 'Butcher,Jim', 'Carlson,Tucker', 'Carrol,Sean', 'Case,Andrew', 'Chernov,Ron', 'Clayton,MegWaite', 'Coben,Harlan', 'Cole,Bobby', 'Connelly,Michael', 'Cornwell,Bernard', 'Cornwell,Patricia', 'Cowie,Amber', 'Crombie,Deborah', 'Crosby,Ellen', 'Cross,Katie', 'Cussler,Clive', 'Delaney,Matthew B.J.', 'Dilts,Tyler', 'Dorsey,Tim']
    f = (0, 0, 400, 300)
    selected_author = show_list_dialog(author_unique, frame=f, name='Select an Author')
    print('list dialog returned:', selected_author)
    author_result.text = str(selected_author)
    return

author_button = ui.Button(title='Author', frame=(10,5,350,100), border_color='black', border_width=2, background_color='#EAECEE', action=select_author, font=('Arial Rounded MT Bold',18))
author_button.width=70
author_button.height=40
view.add_subview(author_button)
#
global author_result
author_entry=''
author_result = ui.TextView(name='author',frame=(100,5,250,40), border_color='black', border_width=3, text=author_entry, font=('Arial Rounded MT Bold',16))
view.add_subview(author_result)

nav_view = ui.NavigationView(view)
nav_view.present('sheet')
cvp

@JonB I hope he will check but I'm not sure that I did not change some code. Anyway, this code recreates the TableView each time your tap the author button...

cvp

@JonB don't forget that line tbl.delegate = MyTableViewDelegate() was initially in the delegate, it can't work.

frankL

I copied the above code and ran it as is. It did not return the selected author. What was printed in the console was:

after wait: None
list dialog returned: None
items: ['Baldacci,David', 'Barr,Nevada', 'Bartol,Amy', 'Bernt,Eric', 'Brandt,Kylie', 'Bruni,Riccardo', 'Bryndza,Robert', 'Burke,James Lee', 'Burton,Mary', 'Butcher,Jim', 'Carlson,Tucker', 'Carrol,Sean', 'Case,Andrew', 'Chernov,Ron', 'Clayton,MegWaite', 'Coben,Harlan', 'Cole,Bobby', 'Connelly,Michael', 'Cornwell,Bernard', 'Cornwell,Patricia', 'Cowie,Amber', 'Crombie,Deborah', 'Crosby,Ellen', 'Cross,Katie', 'Cussler,Clive', 'Delaney,Matthew B.J.', 'Dilts,Tyler', 'Dorsey,Tim'] section, row: 0 4
in delegate: my_sel Brandt,Kylie

JonB

Ok, so the modal_wait is broken -- the after wait prints before anything else!

Possibly we need to add a time.sleep before the modaL wait to ensure the view is presented. Or we need some UI.in_background or on_main_view somewhere...

Have you tried the dialogs module? This is exactly it's purpose, and you don't seem to be doing anything that requires anything custom.

bosco

This appears to be a problem only when running iOS 15 on an iPhone 12. The @JonB example runs fine on my iPad mini, but does not work on my iPhone 12 mini.

I have run into the same problem with some rubicon-objc code i developed.

# works on iPad, but fails on iPhone 12 mini
while self.ispresented:
    waituntil = NSDate.alloc().initWithTimeIntervalSinceNow(.2)
    runLoop = NSRunLoop.currentRunLoop
    runLoop.runUntilDate(waituntil)

Here are some links to others with a similar problem.
https://stackoverflow.com/questions/69312354/failed-to-block-main-thread-with-runloop-on-ios15-with-device-iphone12
https://developer.apple.com/forums/thread/691941

I have other Pythonista scripts that use modal_wait() that do seem to work, so maybe there is a work around

JonB

I wonder if this is a navigation view problem. Try presenting view without creating a nav view.

bosco

@JonB Presenting the view directly without the nav view has the same issue on my iPhone 12. The first line in the console is after wait: None

JonB

A workaround might be to use a Lock.

def show_list_dialog(items=None, *args, **kwargs):
    items = items or []
    tbl = ui.TableView(**kwargs)
    tbl.data_source = ui.ListDataSource(items)
    my_sel = {'value': None}
    import threading
    lock=threading.Lock()
    class MyTableViewDelegate (object):
        def tableview_did_select(self, tableview, section, row):
            print('items:', tableview.data_source.items)
            print('section, row:', section, row)
            my_sel['value'] = tableview.data_source.items[row]
            tableview.close()
            lock.release()
            print('in delegate: my_sel',my_sel['value'])
    tbl.delegate = MyTableViewDelegate()
    tbl.present(style='sheet')
    lock.acquire()
    #tbl.wait_modal()
    print('after wait: ', my_sel['value'])
    return my_sel['value']

See if that solves it

bosco

This code works on my iPhone 12.

I added @ui.in_background to def select_author(sender)

I will also test the Lock code.

import ui
#
def show_list_dialog(items=None, *args, **kwargs):
    items = items or []
    tbl = ui.TableView(**kwargs)
    tbl.data_source = ui.ListDataSource(items)
    my_sel = {'value': None}
    class MyTableViewDelegate (object):
        def tableview_did_select(self, tableview, section, row):
            print('items:', tableview.data_source.items)
            print('section, row:', section, row)
            my_sel['value'] = tableview.data_source.items[row]
            tableview.close()
            print('in delegate: my_sel',my_sel['value'])
    tbl.delegate = MyTableViewDelegate()
    tbl.present(style='sheet')
    tbl.wait_modal()
    print('after wait: ', my_sel['value'])
    return my_sel['value']
#
w, h = ui.get_screen_size()
view = ui.View(name="Frank's Library", bg_color='lightblue', frame=(0, 0, w, h))

@ui.in_background 
def select_author(sender):
    author_unique = ['Baldacci,David', 'Barr,Nevada', 'Bartol,Amy', 'Bernt,Eric', 'Brandt,Kylie', 'Bruni,Riccardo', 'Bryndza,Robert', 'Burke,James Lee', 'Burton,Mary', 'Butcher,Jim', 'Carlson,Tucker', 'Carrol,Sean', 'Case,Andrew', 'Chernov,Ron', 'Clayton,MegWaite', 'Coben,Harlan', 'Cole,Bobby', 'Connelly,Michael', 'Cornwell,Bernard', 'Cornwell,Patricia', 'Cowie,Amber', 'Crombie,Deborah', 'Crosby,Ellen', 'Cross,Katie', 'Cussler,Clive', 'Delaney,Matthew B.J.', 'Dilts,Tyler', 'Dorsey,Tim']
    f = (0, 0, 400, 300)
    selected_author = show_list_dialog(author_unique, frame=f, name='Select an Author')
    print('list dialog returned:', selected_author)
    global author_result
    author_result.text = str(selected_author)
    return

author_button = ui.Button(title='Author', frame=(10,5,350,100), border_color='black', border_width=2, background_color='#EAECEE', action=select_author, font=('Arial Rounded MT Bold',18))
author_button.width=70
author_button.height=40
view.add_subview(author_button)
#
global author_result
author_entry=''
author_result = ui.TextView(name='author',frame=(100,5,250,40), border_color='black', border_width=3, text=author_entry, font=('Arial Rounded MT Bold',16))
view.add_subview(author_result)

view.present('sheet')
#nav_view = ui.NavigationView(view)
#nav_view.present('sheet')

@

JonB

Ok, that makes sense. You can't have a wait_modal on the main thread, since you wouldn't be able to interact with the gui.

frankL

Thank you bosco. That fix works for me on iPhone12.

cvp

@jonb @bosco @frankL 🥂

cvp

@frankL sorry to have searched in the bad direction...

dracosvid

I did that and now it returns the first item in the list (''Baldacci,David') regardless of which item is selected. Where is "selected_row" defined?. .

krishay.baxte

Are you getting and error? Or the delegate just doesn't run?