MobileMoviePlayer and MobileTextField Issues 2024r1.1

Hi Everyone,

I rarely bother y’all with posts, but I thought I should with this. I’d appreciate any help or thoughts you have… and maybe I should have posted as two separate problems…let me know.

I have an iPad app built with Xojo 2024r1.1 being used by quite a few people out there. But two things are occurring that I can and can’t reproduce, and seem to be Xojo control issues:

  1. If an iPad with any version of iOS has an external keyboard connected, and the user clicks into one of the MobileTextField controls, as soon as they type their first character in the field, the app closes completely. But if they disconnect the external keyboard, and try again, it works normally with the on-screen keyboard. They can even reconnect the external keyboard and move around the remainder of the app normally, clicking on all the other controls, as long as they don’t try to type in a MobileTextField. I have been able to reliably reproduce this issue on all my lab ipads, but I can’t find a solution from within the iPads, like settings, etc. Anyone else seeing this?

  2. The same app plays videos from a URL via MobileMoviePlayer. All of my lab iPads play the videos along with their audio without any issues. However, some users have reported no audio… that the videos play on their iPad, but the audio is absent. Checking obvious things with the users like their iPad volume, connected bluetooth audio devices, etc. hasn’t revealed a solution. One user was on iOS 18.3.2, the others I am unsure of. Is anyone else seeing this issue… any thoughts?

Thank you. -mike.

Hi Again,

Ok, I spoke with some friends and found the issue with item 2 in this post, the audio issue during MobileMoviePlayer video playback. If a user has Silent Mode turned on on their iPad (swipe down for the Control Center, then tap the bell icon), the MobileMoviePlayer doesn’t play audio in my app. This is confusing users for the following reason. When they discover that the audio isn’t playing in my app, they wonder if it is an issue with their iPad. So they go straight to Safari and go to youtube.com or some other web site to see if those videos play with audio… and they do play with audio in Safari… so they assume my app is defective.
So I’ve learned that videos you play in Safari from a URL source play with audio even when Silent Mode is on, but yet the MobileMoviePlayer control in my app does not play the audio portion when Silent Mode is on. Should it work this way? I don’t see any documentation on this in the MobileMoviePlayer docs, and I don’t see a Property there that would change this behavior. But if one of my users chooses to watch a video in my app by clicking on it, much like a YouTube video, I’d assume they want to hear the audio and not have it be affected by their Silent Mode selection. Thoughts anyone? And again, thank you. -mike.

so this last part, you can fix by setting your audio category before playing your first video. This can be done with a series of declares (below).

Public Function SetupAudioCategory(byref errormessage as string) As Boolean
  #If TargetIOS
    // + (AVAudioSession *) sharedInstance;
    Declare Function sharedInstance Lib "Foundation" Selector "sharedInstance" (cls As Ptr) As Ptr
    Declare Function NSClassFromString Lib "Foundation" (name As CFStringRef) As Ptr
    
    Var session As Ptr = sharedInstance(NSClassFromString("AVAudioSession"))
    Var error As Ptr
    
    // - (BOOL) setCategory:(AVAudioSessionCategory) category withOptions:(AVAudioSessionCategoryOptions) options error:(NSError * *) outError;
    Declare Function setCategory_withOptions_error Lib "Foundation" Selector "setCategory:withOptions:error:" ( obj As Ptr, category As CFStringRef, options As Integer, outError As Ptr ) As Boolean
    
    // @property (copy, readonly) NSString * localizedDescription;
    Declare Function getLocalizedDescription Lib "Foundation" Selector "localizedDescription" (obj As Ptr) As CFStringRef
    
    Var success As Boolean = setCategory_withOptions_error(session, "AVAudioSessionCategoryPlayback", 1, error)
    If Not success Then
      
      errormessage = getLocalizedDescription(error)
      
      Return False
      
    End If
    
    // - (BOOL) setActive:(BOOL) active error:(NSError * *) outError;
    Declare Function setActive_error Lib "Foundation" Selector "setActive:error:" ( obj As Ptr, active As Boolean, outError As Ptr ) As Boolean
    
    success = setActive_error(session, True, error)
    If Not success Then 
      errormessage = getLocalizedDescription(error)
      
      Return False
    End If
    
    errormessage = ""
    
    Return True
  #EndIf
End Function

Usage:

// Try to set up the audio category
Var message as string
if not SetupAudioCategory(message) then
    // show user a message that audio can't be played if mute switch is engaged
end if

Are you able to reproduce this while running on the device from the Xojo debugger? If so, you should be able to get a crash log telling you exactly what’s causing the crash.

Greg, Thank you for the Delcares. I’ll do that. Also, when I’m back at the lab tonight, I’ll try running with the external keyboard thru the debugger as you suggest and see what happens.
Thank you very much.

Do you have any code in the TextChanged event?

Also, are you logging exceptions and Returning True in App.UnhandledException ?
If you are, this means it’s a hard crash and we’ll need the crash log to understand.
If you aren’t, it might just be an exception in your code that isn’t handled (easier to fix).

Greg, thank you again for the Declares code section. I was able to implement that in just a few minutes, and it works great.

Jeremie, you asked if I have any code in the TextChanged event. I do not; I do not execute any code while the user is typing in the MobileTextField… and there aren’t any threads or anything else executing at the time. The device is just waiting for the user to enter characters… once they’ve entered characters, nothing happens with them until the user clicks an OK button… and it doesn’t matter what that first character is that the user types… the crash happens immediately on the first press of any key. I’m also not attempting to catch anything in App.UnhandledException in this particular project (though I’d be happy to add error trapping there if needed). Since I don’t do anything in any event within the MobileTextField, like the TextChanged event, that’s why I thought others might be seeing this issue with the basic control.
I’m working on running the app in the debugger on two of the physical devices, but I will need another day or two to get it done. I’m having issues running the debugger on the physical device when there is an external keyboard connected. I’ll let you know what I see.
Thank you. -mike.

Hey again,
Ok, so to summarize where I was able to get to, Greg O’s series of declares was a great solution for the MobileMoviePlayer audio problem and beating iPad Silent Mode.

WRT the external keyboard issue, I was finally able to launch the app and debug on device with an external keyboard connected. As expected, after clicking in the MobileTextField to get the cursor, clicking any key on the external keyboard closed the app. But all that appeared in the debugger messages was “09:05:34 PM: Application Launched” and then “09:06:00 PM: Application Ended”… no other messages, and no trapped errors like Nil Object Exception. But again, the MobileTextField works normally without an external keyboard connected.

Trial and error yielded a solution though. The MobileTextField controls that behaved like this were on screens whose super class was iosView still, and not MobileScreen. Changing the super corrected the behavior. Not sure why the MobileTextFields shouldn’t have worked correctly on an iosView with an external keyboard connected since the on-screen keyboard worked fine, and the compiler gave no errors?? If anyone has an idea or workaround, it would be easier for me if I could leave the windows as iosViews for now and have the external keyboards not close the application when clicked. Thank you.