We outlined the tasks to port Candy Kid to Android platform using MonoGame. Now we will focus on iOS.
Let's check it out!
Setup
This post assumes you have Mac OS/X and XCode installed. Also, that you have an Apple Developer account and relevant Certificate(s) and Provisioning Profiles installed to deploy code to iOS devices.
MonoGame
Download and install MonoGame for MacOS. Here is tutorial to create cross platform MonoGame.
Xamarin Studio
Download and install Xamarin Studio. Setup an account; a trial version can be used just to get started!
Launch Xamarin Studio | Click Login. Enter your email + password and click the "Create Account" link.
From here you will be prompted to create a Xamarin account: enter name, email address and password. Check "Start 30-day Xamarin trial immediately". Click Accept. Log in to Xamarin Studio to activate a/c.
Choose File menu | New | Solution. Expand Other | Miscellaneous | MonoGame iPhone/iPad Application.
Project Name: CandyKid.iOS. Choose project Location. Click Create button. Update changes to Main.cs
using System; using Foundation; using UIKit; namespace WindowsGame { [Register ("AppDelegate")] class Program : UIApplicationDelegate { private WindowsGame.AnGame game; public override void FinishedLaunching (UIApplication app) { game = new WindowsGame.AnGame(); game.Run(); } static void Main (string [] args) { UIApplication.Main (args,null,"AppDelegate"); } } }Before writing any new code or porting any existing, ensure the following tasks are completed:
- Rename Game1.cs to AnGame.cs
- Rename all references from Game1 to AnGame
- Use default root namespace of WindowsGame
- Delete Default.png and GameThumbnail.png
Right click CandyKid.iOS project | Options | Build | iOS Bundle Signing. Remove "Entitlements.plist"
Build solution. Error: The minimum deployment for Unified application is 5.1.1, current target is '4.2'
Right click CandyKid.iOS project | Options | Build | iOS Application. Change Deployment Target to 5.2.
Rebuild solution fine. Attach iOS device. Click Play button. The default template code should deploy ok.
Libraries
Candy Kid references the following libraries: Ninject for IoC Container and Xml.Linq for Serialization.
Right click References | Edit References... "All" tab | Scroll to bottom. Check "System.Xml.Linq". OK.
Packages
Right click Packages folder. Right click "MonoGame.Framework.iOS" node. Choose Update as necessary.
Update: at the time of this writing the latest MonoGame.Framework.iOS package is version 3.4.0.459.
However, if you would like to target iOS 9.0 then you can manually download version 3.5.0.628 here.
Right click Packages folder | Add Packages... Enter "Portable Ninject" into Search bar on top right.
Select "Ninject for Portable Class Libraries" | Add Package. Portable Ninject reference also added.
Project Properties
Right click CandyKid.iOS project. Choose Options. Ensure the following options are set on sub tabs:
iOS Application
Application Name | Candy Kid |
Bundle Identifier | Enter bundle identifier |
Version | 1.0.0 |
Build | 1.0.0 |
Devices | Universal |
Deployment Target | 5.2 |
Device Orientation | Landscape Left | Landscape Right |
Status Bar Style | Hide during application launch |
Compiler
Define Symbols | IOS |
Code
Import all C#/.NET code from original XNA 4.0 project. Here are some options to exit game on iOS:
// Option #1. P/Invoke exit(). #if IOS [DllImport("__Internal", EntryPoint = "exit")] public static extern void exit(int status); exit(0); #endif // Option #2. NSThread.exit(). #if IOS Foundation.NSThread.exit(); #endif // Option #3. Throw an exception. #if IOS throw new System.DivideByZeroException(); #endifAlso, if you'd like to upsell full version of your game to unlock then open the url in the native browser:
#if IOS string url = @"Enter URL to full version of game"; UIKit.UIApplication.SharedApplication.OpenUrl(Foundation.NSUrl.FromString(url)); #endifContent
MonoGame iPhone/iPad Application templates add a "Content" folder as default location for all Content.
Right click "Content" folder | Add New Folder. Candy Kid uses the 4x following subfolders (listed below):
Data
Contains flat TXT + XML data files to be consumed by the game. Do not need to be built as XNB files!
Right click each data file | Properties | Build action: Content | Copy to output directory: Copy if newer
Fonts
Font XNB files may need to be rebuilt for Mac OS/X using the MonoGame Pipeline; instructions below:
Right click each font file | Properties | Build action: Content | Copy to output directory: Copy if newer
Sound
Sound effect XNB files may need to be rebuilt for Mac OS/X using the MonoGame Pipeline; see below:
Right click sound effect | Properties | Build action: Content | Copy to output directory: Copy if newer
Song source MP3 files can usually be used as original format; should not need be rebuilt for Mac OS/X.
Right click song file | Properties | Build action: BundleResource | Copy to output directory: Do not copy
Note: there may be issues MP3 songs on low-end devices: MediaPlayer API may cause game to crash!
Also, it may be required to use alias with MediaPlayer API; for example, you may need to write code:
using Microsoft.Xna.Framework.Media; using MediaPlayerX = Microsoft.Xna.Framework.Media.MediaPlayer; public class SoundManager { public void StartMusic() { if (MediaState.Playing != MediaPlayerX.State) { MediaPlayerX.Play(Assets.Song); MediaPlayerX.IsRepeating = true; } } public void PauseMusic() { if (MediaState.Playing == MediaPlayerX.State) { MediaPlayerX.Pause(); } } public void ResumeMusic() { if (MediaState.Paused == MediaPlayerX.State) { MediaPlayerX.Resume(); } } public void StopMusic() { if (MediaState.Playing == MediaPlayerX.State) { MediaPlayerX.Stop(); } } }Finally, it has been noted that the MediaPlayer.Play(Song) API may cause delay when looping MP3 songs;
Alternative: replace MediaPlayer(Song) with SoundEffectInstance, however XNB file will be much larger!
Textures
Copy all source texture images, for example: BMP, JPG, PNG files from the original XNA game project.
Right click texture | Properties | Build action: BundleResource | Copy to output directory: Do not copy
Resources
Update all relevant Universal Icons, Launch Images and iTunes Artwork for iOS device compatibility.
Right click CandyKid.iOS project. Choose Options | iOS Application | Set all icons and images here:
App Icons
iPhone | iOS 5,6 | 57x57 | Icon.png |
iPhone @2x | iOS 5,6 | 114x114 | Icon@2x.png |
iPhone @2x | iOS 7 | 120x120 | Icon-60@2x.png |
iPad | iOS 5,6 | 72x72 | Icon-72.png |
iPad @2x | iOS 5,6 | 144x144 | Icon-72@2x.png |
iPad | iOS 7 | 76x76 | Icon-76.png |
iPad @2x | iOS 7 | 152x152 | Icon-76@2x.png |
Spotlight & Settings Icons
iPhone Spotlight | iOS 5,6 | 29x29 | Icon-Small.png |
iPhone Spotlight @2x | iOS 5,6 | 58x58 | Icon-Small@2x.png |
iPad Spotlight | iOS 5,6 | 50x50 | Icon-Small-50.png |
iPad Spotlight @2x | iOS 5,6 | 100x100 | Icon-Small-50@2x.png |
Spotlight | iOS 7 | 40x40 | Icon-Small-40.png |
Spotlight @2x | iOS 7 | 80x80 | Icon-Small-40@2x.png |
iPhone Launch Images
Standard | 320x480 | Default.png |
Retina (3.5-inch) | 640x960 | Default.png |
Retina (4.0-inch) | 640x1136 | Default-568h@2x.png |
iPad Launch Images
Portait | 768x1024 | Default-Portrait.png |
Landscape | 1024x768 | Default-Landscape.png |
Retina Portait | 1536x2048 | Default-Portrait@2x.png |
Retina Landscape | 2048x1536 | Default-Landscape@2x.png |
iTunes Artwork
Standard | 512x512 | iTunesArtwork.png |
Retina | 1024x1024 | iTunesArtwork@2x.png |
MonoGame Pipeline
If you require MonoGame to build platform specific XNB content files then use the MonoGame Pipeline
Choose Finder | Applications | Pipeline. MonoGame Pipeline launches. Choose File | New. Save project.
Right click project | Add | Existing Item. Add an existing content file e.g. Emulogic.spritefont | Open.
Right click file | Rebuild. An exception may be thrown but the XNB file is still available in bin folder.
Right click project | Add | Existing Item. Add an existing content file e.g. Celebrate.wav file | Open.
Right click file | Rebuild. Assuming Pipeline is installed correctly, the XNB file available in bin folder.
Access Denied
When using MonoGame Pipeline tool, you may receive Access Denied error, especially with MP3 files.
This may be because the ffmpeg binary (and ffprobe binary) needs executable permissions to be set.
Launch Terminal window to manually change executable permissions. Type the following (as root):
cd /Applications/Pipeline.app/Contents/MonoBundle
chmod +x ffmpeg
chmod +x ffprobe
Deployment
Attach iOS device to Mac OS/X. Xamarin Studio, click arrow next to build configuration | Select device.
Click Play button. iOS device launches game as "Evaluation Software". Build will expire within 24 hours.
Alternative: right click CandyKid.iOS project | Archive for Publishing. Click Sign and Distribute button.
Select iOS Distribution Channel as "AdHoc" | Next. Select Signing Identity and Provisioning Profile.
Choose Next to Publish as Ad Hoc. Click Publish button. Choose Location | Save. Now reveal in Finder.
Double click IPA binary file. iTunes launches ok. Select device | Apps | Candy Kid. Click Install | Apply.
Summary
That concludes the Candy Kid port to iOS platform. Outstanding: Candy Kid published on iOS / Android!