Sean
Sean

Reputation: 907

Writing an XML file on an iOS device and have Unity read from it on the same device

I'm wanting to have one app (non Unity project) run in the background and write some data to an XML file. This is code I already have. However, for my Unity app I need to know where the file is located so I can read it it.

Does anyone know where iOS automatically saves the XML file it creates?

Upvotes: 0

Views: 1434

Answers (1)

Wappenull
Wappenull

Reputation: 1389

The question is kinda old but I will answer it here in case someone might need the guideline.

This is quite possible to do now in iOS8.0+, using new App Group feature. This feature allows 2 or more apps to meet in one shared directory. Here is very brief step to set it up:

  1. Go into your Apple Developer agent account, in the same page where you manage app ID and certificates, create new app group. Let's say group.com.company.myapp
  2. We need 2 apps to share data right? Make sure you have 2 app IDs ready, create new if you don't have. Here you can enable App Group Also create 2 app IDs, let's say com.company.myapp.reader and com.company.myapp.writer. (Can be any, you actually don't have to nest the name like this) You can leave app entitlement for app group unchecked for now, as XCode will do all configuration for us.
  3. Create new project on XCode, one for each project, Single view app is a good project template to try.
  4. Turn on "App group" feature on project setting/capabilities tab. Do not forget to select which app group to use.
  5. Here you must write some objective-C code to fetch that shared folder path. (see NSFileManager containerURLForSecurityApplicationGroupIdentifier) UI's viewDidLoad function is nice place to try your code snippet on.
    • Writer app may concatenate this path with filename and try to write some file to that directory, you can use any file API with this path.
    • Reader app do the same but read from it.
  6. Test until you can make reader app see writer app's file. (I will leave all the work here as an exercise, as I said this will be brief)

Specific to OP's scenario:

  1. Ok, you wanted this functionality in Unity3D. Looks like there is no built-in unity's API or any asset store for this, so you have to write your own iOS native plugin. Read some document if you are not familiar with it. The C# stub on unity side can be something like:

    using UnityEngine;
    using System.Collections;
    using System.Runtime.InteropServices;
    
    public static class AppGroupPlugin
    {
    
        /* Interface to native implementation */
    
        #region Native Link
        #if UNITY_EDITOR
    
        private static string _GetSharedFolderPath( string groupIdentifier )
        {
            // Handle dummy folder in editor mode
            string path = System.IO.Path.Combine( System.Environment.GetFolderPath(System.Environment.SpecialFolder.Desktop), groupIdentifier );
            if( !System.IO.Directory.Exists( path ) )
                System.IO.Directory.CreateDirectory( path );
    
            return path;
        }
    
        #elif UNITY_IOS
    
        [DllImport ("__Internal")]
        private static extern string _GetSharedFolderPath( string groupIdentifier );
    
        #endif
        #endregion
    
        public static string GetSharedFolderPath( string groupIdentifier )
        {
            return _GetSharedFolderPath( groupIdentifier );
        }
    }
    
  2. Just make objective-C return you that shared path. I have tested that after you obtain this path, you can use this path on any System.IO.File operation to read write file as if they are normal folder. This can be just one single .m file lying in Plugins/iOS folder.

    char* MakeNSStringCopy (NSString* ns)
    {
        if (ns == nil)
            return NULL;
    
        const char* string = [ns UTF8String];
    
        char* res = (char*)malloc(strlen(string) + 1);
        strcpy(res, string);
        return res;
    }
    
    NSString* _GetSharedFolderPathInternal( NSString* groupIdentifier )
    {
        NSURL *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:groupIdentifier];
        if( containerURL != nil )
        {
            //NSLog( @"Path to share content is %@", [containerURL path] );
        }
        else
        {
            NSLog( @"Fail to call NSFileManager sharing" );
        }
    
        return [containerURL path];
    }
    
    // Unity script extern function shall call this function, interop NSString back to C-string, 
    // which then scripting engine will convert it to C# string to your script side.
    const char* _GetSharedFolderPath( const char* groupIdentifier )
    {
        NSString* baseurl = _GetSharedFolderPathInternal( CreateNSString( groupIdentifier ) );
        return MakeNSStringCopy( baseurl );
    }
    
  3. After you export XCode project from Unity, do not forget to turn on "App Group" capability again.

Upvotes: 2

Related Questions