Threads appear to be killed when iPhone is on lock screen
- Dominant language
- Python
- Stars
- 5.4k
- Forks
- 827
- Avg merge
- 15h 39m
- Merged PRs (30d)
- 40
Description
### Describe the bug
Threads started with `threading.Thread` objects run fine while an iOS app is in the foreground and even when the app is moved to the background, however, if the lock screen is activated, the thread stops working.
This behavior only appears on the device. The simulator doesn't show this bug.
### Steps to reproduce
1. Create a 2-page linked positron-static demo (you can use the fork example [here](https://github.com/alibeyram/toga/tree/main/examples/positron-static)
2. Install the app on a device (This bug does not appear in the simulator)
3. Go to the lock screen
4. Bring the app back to the foreground and clicking the link will not work (the error doesn't happen 100% of the time. Sometimes you need to wait sometime on the lock screen).
5. The error you get in Xcode looks like this
```
[Process] 0x132008e18 - [pageProxyID=13, webPageID=14, PID=13261] WebPageProxy::didFailProvisionalLoadForFrame: frameID=3, isMainFrame=1, domain=NSURLErrorDomain, code=-1004, isMainFrame=1
```
### Expected behavior
App can be brought back from the background after going to lock screen and still functions properly.
### Screenshots
_No response_
### Environment
- Operating System: iOS 16.6
- Python version: 3.10.0
- Software versions:
- Briefcase: 0.3.14
- Toga: https://github.com/alibeyram/toga/tree/main/examples/positron-static
### Logs
```
2023-08-25 13:13:11.063231+0800 Positron[13244:855892] [Process] 0x132008e18 - [pageProxyID=13, webPageID=14, PID=13261] WebPageProxy::didFailProvisionalLoadForFrame: frameID=3, isMainFrame=1, domain=NSURLErrorDomain, code=-1004, isMainFrame=1
```
### Additional context
Replacing the thread with a call to libdispatch seems to improve, but not completely fix this bug. It seems to fix the problem unless you wait several minutes at the lock screen and then you get the same error.
E.g.
```
libdispatch.dispatch_queue_create.restype = objc_id
libdispatch.dispatch_queue_create.argtypes = [c_char_p, objc_id]
queue = libdispatch.dispatch_queue_create(b"com.example.test", 0);
libdispatch.dispatch_async(queue, self.web_server())
```
Contributor guide
Research direction
Run the linked positron-static example on a physical iOS device and reproduce the failure across lock and unlock. Compare the threading.Thread behavior with the libdispatch approach described in the issue; done means the app returns from the lock screen and its link still works reliably.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- ios, python
- Domain
- mobile-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100