Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Anyone interested in accessing the entire iOS SDK API from Unity?

Discussion in 'iOS and tvOS' started by u3dxt, Jul 6, 2013.

  1. sloopidoopi

    sloopidoopi

    Joined:
    Jan 2, 2010
    Posts:
    244
    Hi,
    I make some test with the GUI Basics but have some trouble on my Ipad. When I try to pick a image from photolibrary the app crashes/hangs. In the logfile I see that the problem is that on the Ipad the UIImagePicker has to be inside a UIPopoverController. Is this a known limitation or do I missing something else. If there is a solution some example code would be great.
     
  2. mikemvpi

    mikemvpi

    Joined:
    Dec 19, 2012
    Posts:
    7
    Thank you for the answer! Removing and reinstalling did the trick, but I also had to delete the Library folder. Otherwise, Unity was silently crashing during game start. Now everything seems to work. Thanks!
     
  3. kaz2057

    kaz2057

    Joined:
    Jan 18, 2011
    Posts:
    326
    Hi vitapoly,

    I try to use my simple code to shar ea screenshot. My script is execute in right way because print() is good, but I receive warning in xcode debugger and no image was sharing:

    Thanks
     
    Last edited: Oct 23, 2013
  4. kaz2057

    kaz2057

    Joined:
    Jan 18, 2011
    Posts:
    326
    I modify a part of script
    It seems there is NO ERROR but I cannot see any share window on my monitor.
    In my scene I have just a cube, main camera and gameobject with script attached ...
     
  5. kaz2057

    kaz2057

    Joined:
    Jan 18, 2011
    Posts:
    326
    Ok I tried also TakeScreenshotButton from page7 but is seems identical. Xcode debug that screenshot is fine, print "TAKE SCREENSHOT" but it is not show any facebook share ...
     
  6. u3dxt

    u3dxt

    Joined:
    Jul 6, 2013
    Posts:
    317
    @kaz2057 Unity's Application.CaptureScreenshot does not guarantee when the image is available.Yielding maybe unsafe depending on the device or how busy the cpu is. Try this code:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using U3DXT.iOS.Native.UIKit;
    5. using U3DXT.iOS.Social;
    6. using U3DXT.iOS.Native.Social;
    7.  
    8. public class TakescreenShotButton : MonoBehaviour {
    9.    
    10.     private bool _captured = false;
    11.     void OnGUI()
    12.     {
    13.         if ( GUI.Button(new Rect(0,0,300,50), "Take Screenshot and Share") )
    14.         {
    15.             Application.CaptureScreenshot("screenshot.png");
    16.             _captured = true;
    17.            
    18.             Debug.Log ("TAKE SCREENSHOT: " + Application.persistentDataPath);
    19.         }
    20.     }
    21.    
    22.     void Update()
    23.     {
    24.         if ( _captured  System.IO.File.Exists(Application.persistentDataPath + "/screenshot.png") )
    25.         {
    26.             Debug.Log("screenshot exists: " + Application.persistentDataPath + "/screenshot.png");
    27.             UIImage tmp = new UIImage(Application.persistentDataPath + "/screenshot.png");
    28.             SocialXT.Post(SLRequest.SLServiceTypeFacebook, "combined image test", tmp.ToTexture2D(), "http://www.u3dxt.com", true);
    29.                
    30.             System.IO.File.Delete(Application.persistentDataPath + "/screenshot.png");
    31.             _captured = false;
    32.         }
    33.     }
    34. }
    35.  
    Alternatively, take a look at this tutorial: http://unity3d.tutsmobile.com/how-to-take-a-screenshot-and-share-it-on-ios/
    It is more efficient in terms of speed and memory usage.
     
  7. kaz2057

    kaz2057

    Joined:
    Jan 18, 2011
    Posts:
    326
    I tty also this script but it give me the same result ... Print was fine but Facebook share window not show ...
    I m on ipad4 with iOS 7
    Any help?

    P.s I send you a PM :)
     
    Last edited: Oct 23, 2013
  8. AndrewK

    AndrewK

    Joined:
    Sep 14, 2012
    Posts:
    38
    @u3dxt
    Can you provide the GameCenter matchmaking example with custom UI?
     
  9. kaz2057

    kaz2057

    Joined:
    Jan 18, 2011
    Posts:
    326
    Nothing to do whith social share.

    I try PostRende(), Update() and my OnPress() function using readPixel() and Application.captureScreenshot() but no window sharing is showed ...

    My steps are:
    1) Create project
    2) Import 1.5.0 iOS SDK
    3) Select modules Core and Social (I add also Core Image and Media for testing) and select "Generate link.xml" (but I disable stripping for tests)
    4) Import takeScreenshot scripts.
    5) Create scene.unity3d, add 1 camera, 1 cube and 1 void object (for 3 tests I assign in void object OnPress() and Update() version, in cameraMain PostRender() )
    5) Export

    Unity version 4.2.2f1
    iPad 4, iOS 7
    Xcode 5.0

    Thanks
     
  10. AnuvaTech

    AnuvaTech

    Joined:
    Jul 8, 2013
    Posts:
    7
    Hello U3DXT,
    I am working on a concept in which I need to use gamekit peer to peer connectivity without using peer picker controller. I have written a small plugin to send data from one device to another using Bump integration, which I think can be used to send bluetooth (must.. no wi-fi) session id and/or peer id of the master to the client. Using this, I intend to connect the two devices, so I can proceed with a local multiplayer game. Now, my question is, because I don't know Objective C at all (believe me, I had my fair share of challenges with Bump), I am not sure if it is even possible to connect using session ID / peer ID like the way I am thinking. How can this be done using any high-level or low-level api in iOS SDK Pro? Is it possible? If yes, it would be a worthy investment for me. Cheers!
     
  11. u3dxt

    u3dxt

    Joined:
    Jul 6, 2013
    Posts:
    317
    @sloopidoopi What iOS version and iPad version are you using? It should not crash, but I do remember some view controllers need to use the UIPopoverController instead. We will fix the high-level API call in the next version.

    @AndrewK Do you want to see matchmaking example for realtime or turn-based?

    @AnuvaTech The low-level GKSession allows you to do just that. We don't currently have a working example, but you can download our Basic edition for free and try out the GameKit features. https://www.assetstore.unity3d.com/#/content/11817
    Docs for GKSession is here: http://u3dxt.com/api/?topic=html/T_U3DXT_iOS_Native_GameKit_GKSession.htm
     
  12. u3dxt

    u3dxt

    Joined:
    Jul 6, 2013
    Posts:
    317
    @kaz2057 We am glad to be able to help you offline. Just to recap and for others to know:

    - To use the Facebook, Twitter, and other services native to iOS (not the Facebook app), the user needs to go to the Settings app, and sign in to Facebook or other services.
    - The last argument of SocialXT.Post() is checkServiceAvailable. If you pass in false for that, and the user did not sign in to Facebook in Settings app, it would prompt the user to do that.

    - The option for IAPXT to not use encryption will be added in the next version.
    - Writing to Photo Library is available now in low-level API, but a high-level API will be added in the next version.

    Edit:
    - U3DXT supports stripping with micro mscorlib. If an error comes up when building, try deleting Assets/link.xml or renaming it to something else, just in case.
    - To check if Unity's Mono libs support something: http://docs.unity3d.com/410/Documentation/ScriptReference/MonoCompatibility.html
     
    Last edited: Oct 24, 2013
  13. AndrewK

    AndrewK

    Joined:
    Sep 14, 2012
    Posts:
    38
    Realtime, at first, but I need both. Can you make it? If so, when?
     
  14. u3dxt

    u3dxt

    Joined:
    Jul 6, 2013
    Posts:
    317
    @AndrewK We will add a custom matchmaking UI to the GKMeeting example next week. It won't be as elaborate as the native one, but will have the basics.
     
  15. AndrewK

    AndrewK

    Joined:
    Sep 14, 2012
    Posts:
    38
    Thank you! Can't wait.
     
  16. AnuvaTech

    AnuvaTech

    Joined:
    Jul 8, 2013
    Posts:
    7
    Hi, Thanks for the prompt reply. I looked at the iOS SDK Basic, but I couldn't figure out what to use. It's written that the gamekit is for iOS7. does that mean it won't work on older sdks? I need to target devices from iOS 6 and above. Also, can you please provide a sort of really small template or pseudo code for GKSession manual connections so that I can get the flow of the api in C#? Sorry if it's too much to ask, but I don't know jack sh*t about Objective C low level api and I was interested in iOS SDK for it's high-level api. Also, I'd like to know if I could use the APNS service via this plugin.
     
    Last edited: Oct 25, 2013
  17. u3dxt

    u3dxt

    Joined:
    Jul 6, 2013
    Posts:
    317
    @AnuvaTech Unity already has APNS API, http://docs.unity3d.com/Documentation/ScriptReference/NotificationServices.html.

    In the Basic edition, you can select the "Game Kit with Real-Time and Turn-Based Multiplayer". If you don't have Xcode 5 and iOS 7 SDK installed, you can use this module. If you do have those installed, then you can use the "Game Kit for iOS 7" module. Even if you choose the one for iOS 7, it still works on devices with iOS 5 and up. You just have to make sure you don't use APIs that were introduced in iOS 7. So maybe we should be more clear that the "for iOS 7" means for iOS 7 SDK for the building process.

    We have not tested this, but the code would look like this. BTW, iOS 7 deprecated GKSession and recommends using Multipeer Connectivity instead, which our plugin also offers. It means you can still use GKSession in iOS 7 but it's best to check if iOS 6 and before, use GKSession, and use Multipeer for iOS 7.

    Code (csharp):
    1. GKSession _session;
    2. SessionDataDelegate _dataDelegate;
    3.  
    4. void Setup() {
    5.   _session = new GKSession(null, null, GKSessionMode.Peer);
    6.   _session.PeerDidChangeState += OnPeerChangeState;
    7.   _session.DidReceiveConnectionRequestFromPeer += OnReceiveRequest;
    8.  
    9.   _dataDelegate = new SessionDataDelegate();
    10.   _session.SetDataReceiveHandler(_dataDelegate);
    11.  
    12.   _session.available = true;
    13. }
    14.  
    15. // when a new peer becomes available, auto connect to it
    16. void OnPeerChangeState(object sender, GKSession.PeerDidChangeStateEventArgs e) {
    17.   switch (e.state) {
    18.     case GKPeerConnectionState.Available:
    19.       _session.ConnectToPeer(e.peerID, 10);
    20.       break;
    21.     case GKPeerConnectionState.Connected:
    22.       Debug.Log("Connected.");
    23.       break;
    24.     case ...
    25.   }
    26. }
    27.  
    28. // when receiving a request from peer, auto accept
    29. void OnReceiveRequest(object sender, GKSession.DidReceiveConnectionRequestFromPeerEventArgs e) {
    30.   _session.AcceptConnectionFromPeer(e.peerID, null);
    31. }
    32.  
    33. void SendData(byte[] data) {
    34.   _session.SendDataToAllPeers(NSData.FromByteArray(data), GKSendDataMode.Reliable, null);
    35. }
    36.  
    37. class SessionDataDelegate : GKSessionDataDelegate {
    38.   public override void Receive(NSData data, string peer, GKSession session, string context) {
    39.     Debug.Log("got data: " + data.ToByteArray());
    40.   }
    41. }
    42.  
     
  18. AndrewK

    AndrewK

    Joined:
    Sep 14, 2012
    Posts:
    38
    There is a bug in newest 1.5 ver of plugin:

    At start in Log screen is always information:
    "Local player authentication failed: the requested operation has been cancelled or disabled by the user”

    and if I am not logged in to GameCenter, always failed to show Login UI,
    or if I am logged in there is no info „”Welcome back …”

    Checked on both GameCenter examples.

    iPhone and iPad iOS 7.0.3


    BTW, relating to my previous question about custom UI GameKit example, in the meanwhile, can you write some simple template how to use this function?:

    Namespace: U3DXT.iOS.Native.GameKit
    Assembly: U3DXTGameKit7 (in U3DXTGameKit7.dll) Version: 1.5.0.0
    GKMatchmaker.FindMatch Method

    Code (csharp):
    1. public virtual void FindMatch(
    2.          GKMatchRequest request,
    3.          Action<GKMatch, NSError> completionHandler
    4. )
    and does this function works also on iOS6? If not which one does?



    ----------------------------------------------------------
    EDIT: PROBLEM SOLVED!

    It was no u3dxt bug, it was this one:
    http://forum.unity3d.com/threads/201106-Failed-to-authenticate-local-user-Xcode-5-iOS-7
     
    Last edited: Oct 26, 2013
  19. AndrewK

    AndrewK

    Joined:
    Sep 14, 2012
    Posts:
    38
    OK, I've done something like:
    Code (csharp):
    1.         var request = new GKMatchRequest();
    2.         request.minPlayers = 2;
    3.         request.maxPlayers = 2;
    4.        
    5.         GKMatchmaker.SharedMatchmaker().FindMatch( request, (match, error) => {
    6.            
    7.            
    8.             if (error != null)
    9.             {
    10.                 // Process the error.
    11.             }
    12.             else if (match != null)
    13.             {
    14.                 _myMatch = match; // Use a retaining property to retain the match.
    15.               //  match.delegate = self;
    16.                 if (!_matchStarted  match.expectedPlayerCount == 0)
    17.                 {
    18.                    _matchStarted = true;
    19.                    // Insert game-specific code to begin the match.
    20.                    
    21.                     SetupMatch();
    22.                 }
    23.             }
    24.            
    25.         });
     
    Last edited: Oct 26, 2013
  20. u3dxt

    u3dxt

    Joined:
    Jul 6, 2013
    Posts:
    317
    @AndrewK Sorry we didn't get back to you earlier. But it seems like you got the FindMatch() code working. With a low-level GKMatch, you can actually still use the high-level API by calling RealTimeMatchesController.SetCurrentMatch(gkMatch). Once you call that, it takes some time to resolve players for you, and then sends out the MatchMakerFoundMatch event. You can then use other high-level calls in RealTimeMatchesController and RealTimeMatch. For more info about the high-level implementation, you are welcome to look at the source at https://github.com/vitapoly/u3dxt.

    BTW, all methods, properties, and fields in the API documentation have an Availability section which says what iOS version it was introduced in.
     
  21. kaz2057

    kaz2057

    Joined:
    Jan 18, 2011
    Posts:
    326
    Dear U3dxt,
    Thanks for previous support !

    However today I try to use mail everything script but on start application it crashes ...

    Tomorrow I attach my code debug log.

    I hope in your assistance :)

    Thanks for everything
     
  22. kaz2057

    kaz2057

    Joined:
    Jan 18, 2011
    Posts:
    326
    Ok,

    Today I test a lot of script to send an email

    1) Using low level API from your tutorial
    2) Using SocialXT.Mail

    The error is the same.

    If it is possible can you help me offline like the previous time?
     
  23. AndrewK

    AndrewK

    Joined:
    Sep 14, 2012
    Posts:
    38
    @u3dxt Thank you for you suggestion, but I have some problem with both implementaition, I mean mine, which I attached above, and using your suggestion:

    Code (csharp):
    1.         GKMatchmaker.SharedMatchmaker().FindMatch( request, (match, error) => {
    2.            
    3.             if (error != null)
    4.             {
    5.                 Log(error.LocalizedDescription());
    6.             }
    7.             else if (match != null)
    8.             {
    9.                 _myMatch = match; // Use a retaining property to retain the match.
    10.               //  match.delegate = self;
    11.                 Log ("is Match!" + match.expectedPlayerCount);
    12.                
    13.                 InitRealTime();
    14.                 RealTimeMatchesController.SetCurrentMatch(match);
    15.                 RealTimeMatchesController.Init();
    In both cases expectedPlayerCount always gives me 1.
    Can you help me with that?
     
  24. u3dxt

    u3dxt

    Joined:
    Jul 6, 2013
    Posts:
    317
    @AndrewK Yes, that is true. The matchmaker gives you a match with no players yet. You will need to set the delegate on the match and wait for a player to join.

    We have not completely added a custom UI to GKMeeting example yet, but here is what we have so far, and it works fine. This is added to Main.cs.

    Code (csharp):
    1.  
    2. void CreateMeetingCustom() {
    3.     Log("Creating meeting with custom UI.");
    4.    
    5.     var request = new GKMatchRequest();
    6.     request.minPlayers = 2;
    7.     request.maxPlayers = 4;
    8.  
    9.     GKMatchmaker.SharedMatchmaker().FindMatch(request, OnCustomFoundMatch);
    10. }
    11.  
    12. void OnCustomFoundMatch(GKMatch match, NSError error) {
    13.     if (error != null) {
    14.         Log("Error with matchmaker: " + error.LocalizedDescription());
    15.     } else if (match != null) {
    16.         // set the high-level match, and it will raise MatchMakerFoundMatch event
    17.         RealTimeMatchesController.SetCurrentMatch(match);
    18.     }
    19. }
    20.  
    And in the MatchMakerFoundMatch event delegate up around lines 40s, we commented out the line for checking expectedPlayerCount, and just call StartMeeting() right away.
     
  25. AndrewK

    AndrewK

    Joined:
    Sep 14, 2012
    Posts:
    38
    @u3dxt Thank you! I am amazed with this thing. I am sure, that I did exactly the same things before, but I got crashes when I commented that expectedPlayerCount checking, so I concentrated on that. Now it works. It is miracle I guess.
    Anyway, thank you for your help. Now I can move forward.
     
  26. DokRaphael

    DokRaphael

    Joined:
    Nov 17, 2012
    Posts:
    5
    @u3dxt
    Hi ! I've just bought this plugin.
    Do you have any example of how to do Face detection ?
    ( If possible in C# )
    Thank you !
     
    Last edited: Oct 30, 2013
  27. _Amael_

    _Amael_

    Joined:
    Aug 20, 2012
    Posts:
    19
    Edit: Nevermind! I'm being silly and have found the source of my problem - U3DXT continues to be utterly awesome! :D
     
    Last edited: Oct 30, 2013
  28. Gizmocracy

    Gizmocracy

    Joined:
    Jan 5, 2013
    Posts:
    10
    Love the plugin. So far it exposes every API I need, with one exception: SCNetworkReachability, to tell me whether the user has an Internet connection available. Any chance of adding this to an upcoming release?
     
  29. u3dxt

    u3dxt

    Joined:
    Jul 6, 2013
    Posts:
    317
  30. kaz2057

    kaz2057

    Joined:
    Jan 18, 2011
    Posts:
    326
    Hi Vitapoly, I try to contact you offline :)

    I found a bug using multiple display buffer (airPlay).

    If I use multiple camera buffer for airPlay no social windows (mail, facebook) appears.

    Thanks for support
     
  31. DokRaphael

    DokRaphael

    Joined:
    Nov 17, 2012
    Posts:
    5

    Hi,

    I want to detect faces from live camera.

    thank you for your answer, I will wait for next week.
     
  32. MythicalCity

    MythicalCity

    Joined:
    Feb 10, 2011
    Posts:
    420
    Hi,

    Using the social API with Facebook, is there a way to query the access token and token expiration?

    -JJ
     
  33. u3dxt

    u3dxt

    Joined:
    Jul 6, 2013
    Posts:
    317
    @kaz2057 Using multiple cameras would need to use Application.CaptureScreenshot(). May be the same with AirPlay. To make sure if you are getting a valid screenshot back, maybe display it in Unity after doing the screenshot.

    @capitalJmedia In the coming version, we are adding an account property to the DirectRequestService class, which is the parent of Facebook. That is the low-level ACAccount, which you can get the OAuth access token. I don't think you can get the expiration though.
     
  34. kaz2057

    kaz2057

    Joined:
    Jan 18, 2011
    Posts:
    326
    I have problem just with socialXT.mail without any particular data or attachment ...
    I think would be a low level problem using multiple display buffer (not only simple camera)
     
  35. MythicalCity

    MythicalCity

    Joined:
    Feb 10, 2011
    Posts:
    420
    Thanks for the quick answer!
     
  36. boriel

    boriel

    Joined:
    Jul 2, 2012
    Posts:
    19
    I'm *very* interested, of course (bought the plugin recently for a project, and it's working well).
    Does it support phone vibration? This could be very funny for gaming. :p
     
  37. u3dxt

    u3dxt

    Joined:
    Jul 6, 2013
    Posts:
    317
    @kaz2057 SocialXT.Mail() needs to take in a valid Texture2D for the attachment. Do you mean the problem is you cannot get a screenshot using multiple cameras?

    @boriel Not yet, but we will add it in the next version in a few weeks.
     
  38. kaz2057

    kaz2057

    Joined:
    Jan 18, 2011
    Posts:
    326
    I'm not adding attachment. I just try to send a simple "hello world" email but window do not appear ...
     
    Last edited: Nov 2, 2013
  39. u3dxt

    u3dxt

    Joined:
    Jul 6, 2013
    Posts:
    317
    Version 1.6.0.0 is released with exciting new features, iCloud, export songs from Music Library to storage, export images to Photo Library, and fixes that were promised this week. Just like before, go to Assets->U3DXT->Check for Updates to get the latest. Recommend deleting the whole Assets/U3DXT folder before importing.
     
  40. u3dxt

    u3dxt

    Joined:
    Jul 6, 2013
    Posts:
    317
    @kaz2057 Do you have a mail account setup like before? Does SocialXT.Mail() return true or false? Is there any error output from Xcode?
     
  41. kaz2057

    kaz2057

    Joined:
    Jan 18, 2011
    Posts:
    326
    Hi,

    mail was setting to true without any check ( I used old 1.5).
    However I m trying to use 1.6 and I see that you substitute Texture2D to UIImage. I cannot hower set a "null" UIImage so I must create a UIImage temp = UIImage () to send correctly an email ....
     
  42. u3dxt

    u3dxt

    Joined:
    Jul 6, 2013
    Posts:
    317
    @kaz2057 You can use SocialXT.Mail(...., (UIImage) null, true). Or (Texture2D) null. Both methods do the same thing.
     
  43. kaz2057

    kaz2057

    Joined:
    Jan 18, 2011
    Posts:
    326
    On doc I see that it accept just UIImage and not 2dTexture? I'm wrong?

    EDIT: I see now that you accept 2 different mail string form :)

    P.S: about airplay can you support me offline when you have time? Thanks
     
    Last edited: Nov 3, 2013
  44. MHD-Salka

    MHD-Salka

    Joined:
    Mar 19, 2013
    Posts:
    72
    any plans for Core MIDI Framework support? :D
     
  45. sonicviz

    sonicviz

    Joined:
    May 19, 2009
    Posts:
    1,051
    Inter-App Audio api support?

    ty!
     
  46. u3dxt

    u3dxt

    Joined:
    Jul 6, 2013
    Posts:
    317
    @MHD Salka, @sonicviz They are added to the plan, but no ETA yet.
     
  47. MythicalCity

    MythicalCity

    Joined:
    Feb 10, 2011
    Posts:
    420
    Hi, tried to update but it looks like the version on the Asset Store is still the previous version and when I try to update from the U3DXT menu I get an error connecting to server message.
     
  48. Joskym

    Joskym

    Joined:
    Oct 2, 2013
    Posts:
    39
    Hi,
    We have recently bought your plugin. It sounds awesome but we have multiple problems.
    First of all, if you have the Facebook SDK from Unity, there is a conflict between the Facebook namespace of the Facebook SDK and the Facebook type of your plugin. Is there an easy way to correct this?
    Secondly, we're unable to build:
    We are using Unity 4.2.2 and xCode 5
    Can you help us? (I think a dedicated forum for problems could be nice)
     
    Last edited: Nov 5, 2013
  49. u3dxt

    u3dxt

    Joined:
    Jul 6, 2013
    Posts:
    317
    @capitalJmedia Unity still hasn't approved the new version yet. Can you try update from U3DXT menu again? Maybe connection error before.

    @Joskym To resolve naming conflicts in C#, you can use the full name including namespace. So to fix this one specifically, change it to U3DXT.iOS.Social.Facebook in SocialTest.cs.

    The second one looks like it's an error from the Facebook SDK plugin. We just tried it in combination with U3DXT, and it builds fine after resolving the naming conflicts. It looks like there is a sharing violation with the file. Can you check if the Xcode project file/folder is locked or in used by another app? Maybe you can try building to a new folder and see if that resolves the problem.
     
  50. Joskym

    Joskym

    Joined:
    Oct 2, 2013
    Posts:
    39
    Thank you for your help, resolving the naming conflict resolve the second problem. It's a bit weird because I tried to resolve it by commenting all the SocialTest file and the second error was still here. Is SocialTest needed for the compilation?
     
    Last edited: Nov 6, 2013