Latest SDL2 2.0.26 - iOS dev - Anyone having any success? [SOLVED]

Hello everyone and happy new year,

I’m currently involved in porting a multiplatform game (Windows, Linux, Mac) to iOS. I am using a MacBook Air M1 and the latest version of SDL2 and Xcode.

What I’m stuck on is getting anything running on my iPhone. I have followed the build instructions multiple times to the letter. I can build the SDL2 framework for iOS no problems, I can also build the static library.

It’s when it comes to trying to build a project that uses SDL2. Firstly I get an error with the file SDL_sysurl.m - which appears to be Mac related. It tries to include a Cocoa header file, I can comment that out and it compiles, but then I get an error about the Carbon library being unusable with iOS.

My question is - as of January 2023, who is using SDL2 for iOS development here? I assume many people? Which version of the library are you using? Are there any extra steps needed for this to work? I also have SDL installed via Homebrew on my Mac for Mac development, which I would assume wouldn’t affect it but I guess that’s plausible.

Basically - can anyone lead me towards a tutorial that works with the current version of SDL2 on iOS? If not, is there a prior version that works?

Many thanks in advance, I’ve spent hours on this now and wanted to ask in case it’s something obvious that hasn’t yet made it into the popular tutorials.

Thanks,

Oli

It sounds like you’re trying to use the macOS SDL2. I just checked, and the iOS SDL2.framework doesn’t link against Carbon or try to include it in any way.

When you’re building SDL2 for iOS, make sure you have an iDevice selected instead of Mac Catalyst.

1 Like

Thanks for your help. That sounds logical, I’ll retry it now and see whether I can tweak anything.

One relevant thing is I get this warning:

/Users/ozzeruk/Projects/iOSGames/Test.xcodeproj: Multiple targets match implicit dependency for product reference ‘SDL2.framework’. Consider adding an explicit dependency on the intended target to resolve this ambiguity.

I don’t see any way to specifically set an explicit dependency. I add the framework that says iOS.

Steps I used just now to make a test iOS SDL app:

  1. Build iOS framework (make sure you select “Framework-iOS”, and next to it select “Build->Any iOS Device (arm64)”)
  2. Make a new Xcode project. For this one I chose the “Game” framework, since it doesn’t try to add as unneeded stuff (for macOS choose regular “App” template).
  3. Remove all added source code and other detritus. Leave main.storyboard, LaunchScreen.storyboard, and Assets.xcassets
  4. Copy the iOS SDL2.framework to wherever YouriOSApp.xcodeproject is
  5. In build settings, under General, under Frameworks, Libraries, and Embedded Content, add a new framework. Choose Add Other and then Add Files and then choose your iOS SDL2.framework
  6. This is the annoying part, and isn’t required for SDL3. On iOS, your app needs to run from a class that inherits from UIAppDelegate so it can handle all the various iOS things, like the app going to the background, low memory notifications, etc. Apparently, if you use the iOS static library it includes its own main() function that creates and runs SDL’s own UIAppDelegate for you, which then calls your main(). Since we aren’t using the static library, we have to create this ourself. So:
    6.1) Create a file called iosmain.m
    6.2) Fill it with the code below. It’s just doing the UIAppDelegate thing, which will then call your main()
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

#import <SDL2/SDL_main.h>

#ifdef main
#undef main
#endif

int main(int argc, char *argv[])
{
	return SDL_UIKitRunApp(argc, argv, SDL_main);
}
  1. Add your own main.c and source code.
1 Like

What do you mean by “I add the framework that says iOS”? Are you including the SDL2 Xcode project directly into your own Xcode project or something?

It sounds like you’ve got two SDL2.framework in your project (which makes sense, since there’s already a Mac port), and Xcode doesn’t know which one to use. Maybe create a separate Xcode project for iOS. Put the iOS project file and its own SDL2.framework in a separate folder.

1 Like

That’s right, yes.

In the SDL docs folder there is a file called README-ios.md, step 3 is:

  1. Right click the project in the main view, select “Add Files…”, and add the SDL project, Xcode/SDL/SDL.xcodeproj

In step 9 the README instructs you to add your own source code to the project.


I’m now following your tutorial instead, thanks very much for this, one query though, step 4 - where would I find SDL2.framework? I have compiled SDL2 for the iOS/arm64 target. Though I don’t have a build folder in that project directory tree. When I added the entire SDL project previously, it did then see the frameworks inside of that.

I tried that in the past but it resulted in Xcode wanting to constantly rebuild SDL2, which was annoying. Hence I ignore the SDL docs for building macOS and iOS apps and just do it my way. (the docs’ way was easier for developing SDL-based iOS games on a Mac with an Intel CPU if you wanted to use the Simulator)

  1. Open SDL2.xcodeproj, set Framework-ios and Build->Any iOS Device (arm64 in the status bar up top. (see screenshot)
  2. Go Product->Archive. This will build SDL2 in Release mode. If you were building for macOS this would also build both Intel and ARM binaries.
  3. If the build is successful, the Organizer window pops up and you’ll see the archive. Right click on it, chose Show in Finder
  4. In the Finder window, right click on the archive and pick Show Package Contents. Go to Products->Library->Frameworks.
  5. Copy this SDL2.framework to the same folder as your iOS app’s .xcodeproject. Note: Use the Finder for this! In the past I’ve used the command line and the symlinks inside the .framework got all messed up (maybe I didn’t use the right cp arguments).
2 Likes

FWIW, I think the “official” SDL2 way of doing this is copying SDL_uikit_main.c from the SDL2 source into your project instead of manually creating a file that contains main() which calls SDL_UIKitRunApp())

But as @sjr said, this will be better in SDL3 (there you only need to #include <SDL3/SDL_main.h> in the sourcefile that contains your int main(int argc, char* argv[]) and that’s all).

1 Like

This has worked correctly - thanks very much for your help! It’s much appreciated! I hope I can return the favour one day.

The Product->Archive step was one that I wasn’t aware of before, and filled in the missing gap in my knowledge.

My SDL test program correctly built and ran on my iPhone 12. Success.

Thanks! Yes in the end I had both methods in different test projects and in the end they both worked.

Cool that sounds great about SDL3 - looking forward to it.