How to read a file in a shared Xamarin project? - xamarin

I am using MvvmCross for my Xamarin application, so I have 3 projects: MyProject.Core, MyProject.Droid and MyProject.Touch
I have file.txt in the MyProject.Core project. I want to be able to open and read file.txt from my code in MyProject.Core so that it can be used on both platforms. It sounds simple but I can't figure out how. I found 2 approaches but I don't think they can work for me:
1) I make file.txt an embedded resource and read it at runtime via reflection. But I don't think I can do this in a PCL.
2) I set file.txt to "Copy to output directory", but this won't work either because the resulting package (.ipa or .apk) won't have access to it once it's on the phone (right?)
EDIT
I just thought of a solution that will suffice to my situation:
Add file.txt to MyProject.Core
In the iOS project, add the same file as a LINK in the Resources folder.
In the Android project, add the same file as a LINK in the values folder.
Although I still can not access file.txt from MyProject.Core, I can access the same file from each platform, which is a sufficient solution to my situation. I'll leave the question here in case anyone has an answer to this specific scenario for someone else that needs it.

If the type of your Core project is a NET Standard project you can just use the standard System.IO classes to get hold of the file system.
If it is a PCL (you probably want to upgrade it) you can use the MvvmCross File plugin to access the file system or the PCLStorage nuget. Whichever you prefer.
Using the former you would add the MvvmCross.Plugins.File nuget to core, and both app projects. Then you can add IMvxFileStore in the ctor of the ViewModel or Service you want to inject it. Then start using any of the methods on that interface to operate on the file system.
However, for embedded resources in your PCL you could do something like:
var assembly = typeof(SomeTypeInYourPCL).Assembly;
// some older PCL profiles you need to call .GetTypeInfo() before .Assembly
var stream = assembly.GetManifestResourceStream("whatever.txt");

Related

React Native - multiple targets

I'm creating a RN app that is meant to be some kind of wrapper. It should have multiple targets (like in Xcode) and all its content (images, text, etc.) should be target dependent. Unfortunately, I cannot find any useful informations about how to achieve this without opening Xcode or Android Studio project and create those targets manually (like here). Is there any other solutions for this?
I was still struggling with described problem but I finally found a solution. It's not easy, needs writing a bit of boilerplate code and looks more like a workaround but I hope it will help someone in the future. What I did is I have completed my wrapper app with the resources for one of my targets so I can have visual effect. In the project's root directory I've created a folder with subfolders for each target. Inside each I have put files (images, source code files, other assets) that are target-dependent. Then I've created bash script that takes one argument - target's name. Based on it, it replaces all the target-dependent files from target's subfolder to the original file's destination in the project structure. In this proces all meta-data informations are also replaced so after firing .sh file I can build the app and upload it to both stores. It's really time consuming to create all these apps separately and publish them and it's maybe not the best solution, but at least it works!
On android, you can edit build.gradle files, java or properties, without having to launch Android Studio (which simply uses Gradle)
You can build different type flavours by only changing app/build.gradle
On iOS, that's another story. Project file (.pbxproj) is a mess,and other Workspace/Scheme files are not easy to read or script. So XCode is the way to Go.
I tried to have dynamic target & Info.plist, there are tools to script that like PlistBuddy
in the end, I saw there are many ways to launch a React Native app for developpers. Some prefer the command line, and only VSCode.
Others want to play with native IDE.
By the way, native IDEs are VERY useful.
e.g. : you want to fine-tune your application performance, using XCode view hierarchy debugger or android Studio Layout Inspector (and be sure you don't use to many views), or use any other performance tools these IDEs offer...
In the end, I used react-native-config along with multiple almost similar configs (Info.plist < target < Scheme for each), here's a post giving an overview of the setup.

How is an ActiveX wrapper created with FireBreath?

I've been through the Windows and Mac video tutorials on the FireBreath (FB) website, through all the documentation and even seen the ActiveX example that a person has provided.
It's been an entire week, but I still can't understand how to create a new project in FB. The only thing explained on the website is how to get the FB sln compiled, where the PluginTest example is already coded. Even for the ActiveX example, only the code is given. It isn't explained as to how they created the project.
So how do I create a new project in FB? Should I just take the existing FB sln file and create a new empty project in it? How do I know what classes I should add to the project? How do I edit cmakeLists.txt to recognize my project? How does running prep2010.cmd make my newly added project compile?
If I need to create a wrapper for my ActiveX, how do I go about creating that project in Windows?
If you have been through the windows video tutorials and didn't see how to create a new project then you were obviously not paying attention. The first video tutorial on both windows and mac tells you how to use fbgen to create a new project.
To get text instructions, you can find them fairly easily:
Go to http://firebreath.org and click on "Getting Started". Scroll down to "Creating a new plugin project" and click on the link.
Either method will walk you through essentially the following steps:
1) Install cmake, visual studio, and python (if you don't have any of them)
2) Get FireBreath (the video tutorials suggest using git; I made the tutorials, so you can guess my suggested method).
3) Run fbgen.py with python and follow the steps.
Congratulations! You have now created a new plugin project!
To build it, you'll need to run the prep script appropriate for your platform and then open the build/FireBreath.(sln | xcodeproj) file in (visual studio | xcode). Note that this differs a bit depending on whether you're on Windows or Mac.
The prep script (such as prep2010.cmd) does not make your project compile; instead it uses cmake to generate the project files for that project for your computer which can then be used to build the project, as explained in the pages linked above. You should never modify anything in the build directory directly, instead you should modify the CMakeLists.txt file in your project directory or if you have platform-specific changes you need to make you can modify Win/projectDef.cmake and Mac/projectDef.cmake.
FireBreath.org is a wiki, so feel free to help us make these things easier to find; as you can see from the links all of the information is there. To me it seems easy to find, so obviously I'm not a good one to try to fix the problem (since I can't see it).
As for making an ActiveX wrapper, there is an example of doing this but it's not really something that is just "easy to do". FireBreath does not in any way attempt to make this a simple thing to do -- that's not the purpose of FireBreath. FireBreath is simply a framework for creating browser plugins; if you want your plugin to act as an activex wrapper you'll have to implement all of the activex for containing your control yourself.
Hopefully that's enough information to get you started. If you are confused, please go read those links. If you're still confused, read them again -- all of this information is there. If you're still confused, come ask in the FireBreath chat room on IRC and I'll try to help you figure it out.

Importing an Xcode project into another one

I am trying to integrate one application into another and I thought that a simple way of doing this may be to add the one application into another. (Simply going to File->Add Files to "Project")
However, when I do this and try to use files that are in that other project, it says that the files can not be found. Am I doing something wrong, or is doing this even the correct way of going about this?
Depending on what you're trying to do, you could either just import the source files (not the project file itself), or you could make the part of the original project you want to use into a framework (library). Then you import the entire framework in one step.
You just add the project (project A) and configure it as a dependency of the app (project B).
If it's iOS, you likely want to deal with this shared program using a library.
If OS X, then you still need to link to what symbols you reference (e.g. create a library). If you just want to bundle a helper app or executable with your app, add it as a dependency, then you'll probably want to copy the product (project A.app) as a resource to your bundle of project B.app. If you only want to build or test, then a simple dependency will do.
If you're really sharing sources, look into using a library (static, dynamic, framework) rather than copying your sources or their references.

How to build and copy class library to output withot referencing it in Visual Studio?

I am working on extensible web-application with plug-ins support. Each plug-in is located at separate class library project and implement some predefined IPluginInterface from common library. Application should load them on start using MEF. What I need to do is automatically build all plug-in projects in my solution and copy them into bin folder of my host project on every solution rebuild. Host application don't need to know anything about concrete plug-in implementations, so I don't want to add reference to these class libraries from it.
I know that it could be done with some command line script, but maybe there is easier way to do that?
Thanks.
I don't know of any built in way. I currently use the following in the post build command line (Application being my host app):
XCOPY "$(ProjectDir)$(OutDir)*" "$(SolutionDir)Application\bin\Debug\*" /y
XCOPY "$(ProjectDir)$(OutDir)*" "$(SolutionDir)Application\bin\Release\*" /y

Installing IB plugin

I have created IB kit plugin now i want to use that plugin in other Xcode project
how to do that? I have tried developers guide but not able to get that done ..please answer
First of all, I assume that you want your plug-in to be embedded within your application's bundle. If not, you can place the IBPlug-in framework in a standard location like /Library/Frameworks.
Creating the Plug-in
Once you have an IBPlugin project created in XCode using Apple's template, you need a little tweak:
Change the name of your framework target so it differs from the Plug-in's. For instance, you could call it MyIBPluginFramework.
In the Target Properties > Build : Modify the Installation Directory of MyIBPluginFramework to #loader_path/../Frameworks.
Also set its Dynamic Library Install Name to #executable_path/../Frameworks/$(CONTENTS_FOLDER_PATH)/$(PRODUCT_NAME).
Set the Installation Directory of MyIBPlugin to #loader_path/../Frameworks/Resources.
(when built, the plug-in is placed in the Resources directory of the framework).
At this point, it should work both in Interface Builder and in IBCocoaSimulator.
Embedding in an application
Drag the IBPluginFramework.framework folder to the Linked Frameworks group of the application's project. Edit your application target: append to Frameworks Search Paths the path #loader_path/../Frameworks/MyIBPluginFramework/Resources.
You're now able to link against the framework and the plug-in, but the framework must be copied to the Frameworks directory of your application when building. Add a Copy Files phase to your target, and drag the framework into.
I cannot garantee success (I managed to make mine work, but might have forgotten to relate a step here), but you're given the big lines.
I thought that usually you put plugins in to the application specific folder found in the Library folder either at the root or user level, e.g.
/Library/Interface Builder 3.0/
On my system I have another folder under that called "Library", and under that called "User Objects" which is empty.
So I would try putting it in each of these folders in turn, restarting XCode and Interface Builder each time (just to be sure)
/Library/Interface Builder 3.0/
/Library/Interface Builder 3.0/Library
/Library/Interface Builder 3.0/Library/User Objects
Hope that helps.

Resources