Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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
6
Question by StewVanB · Apr 10, 2017 at 01:47 PM · iosmobilefilesnative plugindllimport

iOS open docx file from Application.persistentData

I have written a mobile unity app that needs to open a downloaded docx file. I can do this on my android build by simply calling Application.OpenUrl(myPath); and it works fine.

I found that it is not so simple in iOS. I have written a small plugin to use the native iOS code to launch the files. At first the code would crash the app when i would click the button that calls the plugin. But I "fixed" the issue that was causing the crash but now nothing is happening when I call the plugin to launch the file.

The logic steps didn't change just the methods and arguments used.

This is the unity class for launching the file:

 using System;
 using System.Collections;
 using System.Collections.Generic;
 using System.Runtime.InteropServices;
 using UnityEngine;
 
 public static class FileLauncher {
 
 #if UNITY_IOS
     [DllImport ("__Internal")]
     private static extern bool _canOpenURL(string _url);
 
     [DllImport ("__Internal")]
     private static extern void _openURL(string _url);
 #endif
 
     public static void LaunchFile(string _path){
         #if UNITY_IOS
         try{
             if(Application.platform == RuntimePlatform.IPhonePlayer){
                 if(CanOpenURL(_path)){
                     _openURL(_path);
                 }
                 else{
                     Debug.Log("FILELAUNCHER: canopen false");
                 }
             }
         }
         catch(Exception _err){
             Debug.Log("FILELAUNCHER: " + _err.Message);
         }
         #else
 
         Application.OpenURL(_path);
 
         #endif
     }
 
     public static bool CanOpenURL(string _path){
         #if UNITY_IOS
         try{
             if(Application.platform == RuntimePlatform.IPhonePlayer){
                 return _canOpenURL(_path);
             }
         }
         catch(Exception _err){
             Debug.Log("FILELAUNCHER: " + _err.Message);
             return false;
         }
         #endif
         return true;
     }
 
 }

And this is the current plugin I have written:

 #import <Foundation/Foundation.h>
 #import <UIKit/UIKit.h>
 
 @interface SampleClass : NSObject
 
 -(bool)CanOpenURL:(NSString *)_url;
 -(void)OpenURL:(NSString *)_url;
 
 @end
 
 @implementation SampleClass
 
 -(bool)CanOpenURL:(NSString *)_url{
     UnitySendMessage("AppController", "iOSLog", "CanOpenURL");
     if([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:_url]]){
         return YES;
     }
     return NO;
 }
 
 -(void)OpenURL:(NSString *)_url{
     UnitySendMessage("AppController", "iOSLog", "OpenURL");
     NSURL *url = [[NSBundle mainBundle] URLForResource:_url withExtension:@"docx"];
     if(url){
         UIDocumentInteractionController *docController = [UIDocumentInteractionController interactionControllerWithURL:url];
         UIViewController *viewController = [[[[UIApplication sharedApplication]delegate]window]rootViewController];
         [docController presentOpenInMenuFromRect:CGRectZero inView:viewController.view animated:YES];
     }
     else{
         UnitySendMessage("AppController", "iOSLog", "OpenFailed");
     }
 }
 
 @end
 
 extern "C"
 {
     bool _canOpenURL(NSString* _url){
         SampleClass *test = [[SampleClass alloc] init];
         return [test CanOpenURL:_url];
     }
     
     void _openURL(NSString* _url){
         SampleClass *test = [[SampleClass alloc] init];
         [test OpenURL:_url];
     }
     
     char* cStringCopy(const char* _string){
         if (_string == NULL){
             return NULL;
         }
         char* res = (char*)malloc(strlen(_string) + 1);
         strcpy(res, _string);
         return res;
     }
 }

I do not have a background in iOS so I am thinking i am overlooking a step or something simple in the interaction between iOS and unity that someone on here may see immediately.

Thanks for your help!

Comment
Add comment · Show 3
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 martejpad · Oct 27, 2017 at 09:55 AM 0
Share

Hi @wolftamer389! I'm looking to do exactly this and I'm wondering if you managed to find a good solution? If so, would you $$anonymous$$d sharing it? I would be extremely grateful! Thanks a lot

avatar image StewVanB martejpad · Oct 27, 2017 at 01:54 PM 0
Share

I am not sure what type of file you are trying to load but I ended up using the Prime31 package called Etcetera. It allows me to launch a WebView with the document the way I wanted.

avatar image martejpad StewVanB · Oct 27, 2017 at 02:18 PM 0
Share

Thanks!! I came across that plugin while I was searching for solutions and it definitely looks like a good option if you're going to use the functionality often.

I actually got the plugin working, your code helped me a lot getting started so thanks for sharing! I believe what's happening with your code is that you're not specifying the right UIViewController. If you're interested in giving it another try I will more than happy share my code.

2 Replies

· Add your reply
  • Sort: 
avatar image
5

Answer by martejpad · Oct 27, 2017 at 02:34 PM

Hi everyone,

I thought I'd share a working plugin that opens a document within an iOS app, as @wolftamer389 was attempting. The document path is specified from a Unity script. Please bare in mind that this is my first time writing Objective-C code and dealing iOS plugins!

 #import <Foundation/Foundation.h>
 #import <UIKit/UIKit.h>
 
 
 @interface DocumentHandler : NSObject <UIDocumentInteractionControllerDelegate>
 {
     NSURL * fileURL;
 }
 
 - (id)initWithURL:(NSURL*)unityURL;
 
 - (void)UpdateURL:(NSURL*)unityURL;
 
 - (bool)OpenDocument;
 
 - (UIViewController *) documentInteractionControllerViewControllerForPreview: (UIDocumentInteractionController *) controller;
 
 @end
 
 
 @implementation DocumentHandler
 
 - (id)initWithURL:(NSURL*)unityURL
 {
     self = [super init];
     fileURL = unityURL;
     return self;
 }
 
 - (void)UpdateURL:(NSURL*)unityURL {
     fileURL = unityURL;
 }
 
 - (bool)OpenDocument {
     
     UIDocumentInteractionController *interactionController =
     [UIDocumentInteractionController interactionControllerWithURL: fileURL];
     
     // Configure Document Interaction Controller
     [interactionController setDelegate:self];
     
     [interactionController presentPreviewAnimated:YES];
     
     return true;
 }
 
 - (UIViewController *) documentInteractionControllerViewControllerForPreview: (UIDocumentInteractionController *) controller {
     return UnityGetGLViewController();
 }
 
 @end
 
 
 
 
 static DocumentHandler* docHandler = nil;
 
 // Converts C style string to NSString
 NSString* CreateNSString (const char* string)
 {
     if (string)
         return [NSString stringWithUTF8String: string];
     else
         return [NSString stringWithUTF8String: ""];
 }
 
 
 extern "C" {
     
     bool OpenDocumentOnIOS (const char* path)
     {
         // Convert path to URL
         NSString * stringPath = CreateNSString(path);
         
         NSURL *unityURL = [NSURL fileURLWithPath:stringPath];
         
         if (docHandler == nil)
             docHandler = [[DocumentHandler alloc] initWithURL:unityURL];
         
         else
             [docHandler UpdateURL:unityURL];
             
         [docHandler OpenDocument];
         
         return true;
     }
 }


Simply add this file as a .mm in your Classes folder inside the Xcode project exported by Unity. Finally, to call this function from a Unity script, do the following:

 #if UNITY_IOS
 [DllImport ("__Internal")]
 internal static extern bool OpenDocumentOnIOS (string path);
 #endif

And then call your the function normally.

I really hope this helps!

Comment
Add comment · Show 5 · 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 lanrosta · Dec 21, 2017 at 08:20 PM 0
Share

@martejpad - What did you name the .mm file as when you put it in the XCode 'Classes' folder? I am having issues getting you code to work. Help is greatly appreciated.

avatar image martejpad lanrosta · Dec 29, 2017 at 06:53 PM 0
Share

Hi @lanrosta, really sorry for the delay. I didn't name my file anything special, just OpenDocument.mm. What are you having trouble with? Hope you've managed to solve your issue :)

avatar image keop · Jun 29, 2018 at 10:22 AM 0
Share

I just wanted to thank you, it is very useful!

avatar image naviln · Jan 06, 2019 at 06:47 AM 0
Share

This is amazing, thanks! I got it working on my app. It launches the document on iOS, without losing context of the app as well. Great!

avatar image callamfry · Mar 20, 2019 at 04:29 PM 0
Share

@martejpad Thanks for providing this it's extremely helpful when I know very little about writing iOS plugins. I'm trying to convert this to make it work with pdfs stored remotely at a https url is there any help you can give me? I feel like it probably only needs a small change but I'm struggling to figure it out as the viewer opens but there's nothing displayed. this is the error I'm getting in xcode

$$anonymous$$YAPP[333:37903] [default] QLUbiquitousItemFetcher: could not create sandbox wrapper. Error: Error Domain=NSPOSIXErrorDomain Code=2 "couldn't issue sandbox extension com.apple.quicklook.readonly for '/https:/$$anonymous$$YAPP.com/assets/resources/$$anonymous$$YPDF.pdf': No such file or directory" UserInfo={NSDescription=couldn't issue sandbox extension com.apple.quicklook.readonly for '/https:/$$anonymous$$YAPP.com/assets/resources/$$anonymous$$YPDF.pdf': No such file or directory} #PreviewItem

avatar image
0

Answer by Pascal- · Dec 07, 2018 at 11:53 AM

Hello @martejpad,

Sorry, I'm new with IOS. I'd like to know how to open a pdf stored in the steaming assets folder in a pdf reader app using your plugin. How to do so with a unity script? It's pretty simple on Android, but with IOS it seams more difficult.

Thanks a lot for your help, Pascal

Comment
Add comment · 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

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

106 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Native plugin problems with varargs on iOS (Opus) 0 Answers

Updating my game on Play Store or App Store 0 Answers

Substance - Procedural Materials - runtime edit - mobile 1 Answer

Reuse iTween component for multiple small animations 0 Answers

Mobile Shader for Spotlight 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