Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 11 Next capture
2021 2022 2023
1 capture
11 Jun 22 - 11 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
5
Question by jared · Jan 14, 2010 at 12:14 AM · iphonepluginxcode

Specific steps to set up a plugin for iphone in XCode

I understand that plugins are now supported when building for iphone in Unity.

The unity documentation does not spell out any specifics on how to set up the XCode project for building a plugin for this.

When i go to create a new project in XCode, the only 'Bundle' option is under the Mac OS X section and not iphone OS. if i select that and then change the architecture in the project settings to 'iPhone Device 3.0' and add a code signing identity, i get 139 errors when i try to build.

i would appreciate some help from anyone who has successfully created a plugin for iphone, and the specific steps they had to take to get the project set up correctly.

thanks!

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
11
Best Answer

Answer by Robert · Jan 15, 2010 at 10:02 AM

You need to add some code to the Xcode project that is built when you Build for iPhone.

It's quite a process to get the workflow for this right, but it's worth doing the homework. I published my project once to a folder named 'Unity-iPhone' in my Unity project folder, copied it out to a new, separate location, and then added the following script to my Unity project's Assets/Editor/ folder as PostprocessBuildPlayer (making sure to give executable permissions to the file):

#!/bin/bash
cp -f ./Unity-iPhone/Data/* ~/Documents/Xcode/my-project/Data/.
cp -f ./Unity-iPhone/Libraries/* ~/Documents/Xcode/my-project/Libraries/.

What this does is copy all the bits that actually change in an Xcode build and leaves the rest of your project intact. I have lost one too many days trusting Unity's own 'Append' feature.

You can then develop happily in Xcode in the ~/Documents/Xcode/my-project project. To get the plugin going, first rename ProjectAppDelegate.m to ProjectAppDelegate.mm. This tells the compiler to process C and C++ code in the file (or something). Then, above the @implementation line near the top, add:

static ProjectAppDelegate delegateObj;

Then, in your applicationDidFinishLaunching method, you set this value:

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    delegateObj = self;
    ...
}

This allows your plugin's C code to talk to your application's Objective-C code.

Then add the following code at the bottom of the App Delegate .mm file. I have included a sample of how to pass structured data back and forth (I struggled with this, should save you some time).

NSString* CreateNSString (const char* string) { return [NSString stringWithUTF8String: string ? string : ""]; }

char* MakeStringCopy (const char* string) { if (string == NULL) return NULL; char* res = (char*)malloc(strlen(string) + 1); strcpy(res, string); return res; }

struct MyStruct { char* stringValue; int intValue; };

extern "C" {
void _PassStructFromObjCToUnity ( struct MyStruct *myStruct ) { NSLog(@"_PassStructFromObjCToUnity");

     myStruct->stringValue = MakeStringCopy([delegateObj.someStringProperty UTF8String]);
     myStruct->intValue = [delegateObj.someNSNumberProperty intValue];

     printf("-> myStruct->stringValue %s\n", myStruct->stringValue);
     printf("-> myStruct->intValue %s\n", myStruct->intValue);
     NSLog(@"-> complete.");
 }

 void _HaveObjCDoSomething () {
     NSLog(@"_HaveObjCDoSomething");
     [delegateObject doSomething];
     NSLog(@"-> complete.");
 }    

}

Finally, in Unity, in a C# class in Assets/Plugins/, you'd have something like:

using UnityEngine; using System.Runtime.InteropServices;

public struct MyStruct { public string stringValue; public int intValue; }

public class OBJCPlugin { [DllImport ("__Internal")] private static extern void _PassStructFromObjCToUnity ( ref MyStruct myStruct );

 public static MyStruct PassStructFromObjCToUnity ()
 {
     Debug.Log("OBJCPlugin.PassStructFromObjCToUnity");
     MyStruct data = new MyStruct();
     if ( Application.platform == RuntimePlatform.IPhonePlayer )
     {
         _PassStructFromObjCToUnity( ref data );
     }
     return data;
 }    

 [DllImport ("__Internal")]
 private static extern void _HaveObjCDoSomething ();

 public static void HaveObjCDoSomething ()
 {
     Debug.Log("OBJCPlugin.HaveObjCDoSomething");
     if ( Application.platform == RuntimePlatform.IPhonePlayer )
     {
         _HaveObjCDoSomething();
     }
 }

}

Of course, there is more to it than just what you have here, but this is a good kickstart. Have fun :)

Comment
Add comment · Show 10 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image jared · Jan 18, 2010 at 10:25 PM 0
Share

thanks for the info. that's very helpful!

the main point of my confusion was that i was under the impression that 'plugins' for iphone worked the same way as if you were building for pc/mac: a precompiled bundle that unity loaded and accessed through interop. i see now that on iphone, it is just the ability to access objC code that has been added to the xcode project. very misleading nomenclature using the term 'plugin' for both.

avatar image slippdouglas jared · Apr 24, 2014 at 01:26 PM 0
Share

Please do not write thank-yous as answers. You can click the “add new comment” link below any question or answer to comment on that portion; you can also use a @username reference to reply to a specific user.

avatar image Dimitris 1 · Aug 19, 2010 at 11:00 AM 0
Share

If you change your PostprocessBuildPlayer script to the following, it copies files recursively, adding subfolders (such as added video files etc):

!/bin/bash

p -Rf ./Unity\ Player/Data/ ./Xcode\ Project/Data/. cp -Rf ./Unity\ Player/Libraries/ ./Xcode\ Project/Libraries/.

avatar image Colin 1 · Jan 07, 2011 at 08:05 PM 0
Share

I have tried using this PostprocessBuildPlayer script but I get a runtime error when running with the copied libs. "Failed to load AOT module 'mscorelib' while running in aot-only mode."

avatar image slippdouglas Colin 1 · Apr 24, 2014 at 01:26 PM 0
Share

Please do not comments as answers. You can click the “add new comment” link below any question or answer to comment on that portion; you can also use a @username reference to reply to a specific user.

avatar image enekochan · Apr 02, 2012 at 03:01 PM 0
Share

Just two details...

The static delegate object should be declared as a pointer. So this:

static ProjectAppDelegate delegateObj;

Should be changed to:

static ProjectAppDelegate *delegateObj;

And to make all this work on the Simulator, inside Unity3D in "Player Settings" for iOS you have to change the "SD$$anonymous$$ Version" to a Simulator version ("iOS Simulator Latest" for example) and then change in the Xcode project the file "Libraries/Register$$anonymous$$ono$$anonymous$$odules.cpp" and take out of the "#if !(TARGET_IPHONE_SI$$anonymous$$ULATOR)" block the definition of this function:

 void                mono_dl_register_symbol (const char* name, void *addr);

And of course the registration of your functions:

 mono_dl_register_symbol("_PassStructFromObjCToUnity", (void*)&_PassStructFromObjCToUnity);
 mono_dl_register_symbol("_HaveObjCDoSomething", (void*)&_HaveObjCDoSomething);

Hope this helps somebody. By the way I'm using Unity3D 3.5.0f5.

avatar image enekochan · Apr 05, 2012 at 09:49 AM 1
Share

I've created an script that changes automatically the "Libraries/Register$$anonymous$$ono$$anonymous$$odules.cpp" file. It's not very "elegant" but it's the first time I use awk. I've also included the script from Dimitris with it to use all together in "Assets/Editor/PostprocessBuildPlayer": #!/bin/bash

cp -fR ./iOS\ Build/Libraries ~/Documents/Xcode/Xcode\ Project/

cp -fR ./iOS\ Build/Data ~/Documents/Xcode/Xcode\ Project/

rm file.tmp

awk '

{

if ($0 == "#if !(TARGET_IPHONE_SI$$anonymous$$ULATOR)" && NR == 9) {

 getline var1;

 getline var2;

 printf "%s\n%s\n%s\n", var2, $0, var1 >> "file.tmp"

} else if (NR == 32) {

  printf "#endif // !(TARGET_IPHONE_SI$$anonymous$$ULATOR)" >> "file.tmp"

  printf "\n%s\n", $0 >> "file.tmp"

} else if ($0 == "#endif // !(TARGET_IPHONE_SI$$anonymous$$ULATOR)" && NR > 32) {

} else {

 print $0 >> "file.tmp"

}

}' ~/Documents/Xcode/Xcode\ Project/Libraries/Register$$anonymous$$ono$$anonymous$$odules.cpp

mv file.tmp ~/Documents/Xcode/Xcode\ Project/Libraries/Register$$anonymous$$ono$$anonymous$$odules.cpp

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

3 People are following this question.

avatar image avatar image avatar image

Related Questions

Adding files and frameworks to xcode automatically after build button 1 Answer

How would I debug a Unity-plugin from XCode? 3 Answers

Have to "Replace" iOS project every build because of Linker Errors 0 Answers

How to solve ITMS-90809: Deprecated API Usage? 0 Answers

Can I get the Unity3D engine version in Xcode and how to do a conditional compile based on the version? 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges