Cocoa Frameworks: Using one framework inside of another - objective-c

I'm building a framework (main) which uses another framework (sub). Main framework will be used then in different apps.
The main framework target builds without errors. However, if I try to build an App which uses the main framework I receive an error -> Class in the main framework cannot find/import the sub framework...
How can I configure main framework so that it will find the sub framework?

As I understand you want to create one framework inside another. It is called "Umbrella framework" and it's not a good idea.
Documentations says:
Don't Create Umbrella Frameworks
While it is possible to create umbrella frameworks using Xcode, doing
so is unnecessary for most developers and is not recommended. Apple
uses umbrella frameworks to mask some of the interdependencies between
libraries in the operating system. In nearly all cases, you should be
able to include your code in a single, standard framework bundle.
Alternatively, if your code was sufficiently modular, you could create
multiple frameworks, but in that case, the dependencies between
modules would be minimal or nonexistent and should not warrant the
creation of an umbrella for them.
You can use one framework inside another, but both frameworks must be included to your app target and must be copied to /Contents/Frameworks/ directory of your app bundle. Also you must set Installation directory to #executable_path/../Frameworks for both frameworks.

Related

changing the dll's target framework from .NET Framework to .NETCORE

I have the source code of a dll project that Targets .NET Framework. And I'm current developing a Universal App, I want to reference that dll to my project but it is not applicable since the Universal App uses a .NET CORE and that dll is specifically targets .NET Framework.
I'm thinking that I can change the dll's Target Framework since I have the source code but I don't know how.
Or is there another way of solving this?
I don't think there's an automated way to convert the library directly (if anyone knows a way, would be more than happy to hear about it).
However, sine you have the source code you can manually move the code.
Create a new Universal Application Class library and start move the code from the old library in there.
Chances are, not everything will work, since there are pretty major differences between namespaces and APIs between .NET framework and .NET core but at least you'll know what you need to change. I would recommend a modular approach where you include portions of the library, make sure it compiles and so on.

I can't add a reference to ServiceModel in a portable library project

I testing an UWP application and I want to use a proxy to consume a WCF service. I have a proxy that is a library for .net 4.6 but I can't add this project as reference in the project of universal application. It is normal because is a library for .net 4.6.
So I am trying to create a portable library and I have two options, to create a portable library. This option let me say what targets can I use. I select .net 4.6 and windows universal 10.0. The problem is that I can't add a reference to the System.ServiceModel that I need to use the proxy.
The other option is portable library for windows universal. In this cases I can't select the target projects, it has sense because it is only for universal applications. In this case I can add the reference to the System.ServiceModel.
I know that in a portable library I only can use the libraries of the target project more restrictive, in this case I guess that is windows universal, no .net 4.6. But then, why do I can add the reference in the portable library for universal applications and not in the portable library in which I am using .net?
I would like to have a generic portable library to be able to use the proxy in WPF applications and universal windows applications.
Thanks.
Unfortunately there isn't a simple subset relationship between different target frameworks; i.e. in your case UWP is not a subset of .NET 4.6, therefore when you create a portable class library targeting both, you don't simply have all the APIs from the smaller framework available.
When dealing with clientside System.ServiceModel code the situation is even more confusing: although both target platforms include basic support for WCF proxies, the APIs are different enough that there is no portable equivalent that would be available when creating a PCL. This is the reason for the behavior that you are seeing: you can create a proxy both in a .NET 4.6 class library and in a UWP class library, but you can't create it in a portable class library targeting both of them. You will need to create 2 separate libraries.
If you're only going to call the proxies from the platform specific WPF an UWP code, then this shouldn't really be a problem, but I suspect that you would like to call them from the business logic code which you would prefer to implement in a portable class library.
You can achieve this as follows:
Create an interface for the proxy class in a common portable class library for UWP and .NET 4.6.
Reference this common library from both platform specific class libraries: UWP and .NET 4.6. The proxies in these 2 libraries should implement the common portable interface. I haven't tried it, but if you configure the service references to reuse the types from your portable class library, the generated proxies should already implement your interfaces. This way you could avoid create wrappers around your proxies in each of the platform specific class libraries.
You can now write business logic in the common portable class library and only ever work with proxies using the common interface. To get concrete instances of this interface on each platform use a portable dependency injection framework, such as Ninject.
In application code for each platform you will then initialize the dependency injection framework by registering the correct proxy implementation of the interface, either UWP one or .NET 4.6 one. Of course you will also reference the common portable class library from both applications, as well as the correct platform specific class library in each application.

ASP.NET 5 and Build Action

I have a Web Site and Class Library built with ASP.NET 5. The Class Library depends on an set of external files (XML, EXEs, etc.). Those dependencies are added as part of the project and visible in the Solution Explorer of Visual Studio.
My Web Site has a dependency on the Class Library. When I build the Web Site, I would expect the dependencies of the Class Library to be copied to the Web Site, but they aren't.
The Build Action (Copy always, Copy if changed) appears to be gone with ASP.NET 5. How do I make sure that dependencies other then the DLL of the Class Library itself gets copied to the Web Site project?
First thing first, they won't be in src/yourProject/bin/Debug. Those have been moved to the artifacts folder.
Also, your project by default will not output DLLs. This is mainly due to performance reason but if you need your DLL to publish your application, check your project properties. In the Build section you should have an option called Produce outputs on build. Tick that and bingo.
You have your dlls. Most of the time (aka: while coding), you won't need them since they will always be recompiled in memory.
You need to manually add a pre/post build step in project.json

Frameworks for static libraries xcode

I have just added a linked library to my project using the question here Process for linking static ObjC libraries in XCode and the document linked to in the answer.
I happen to know the library uses CoreData objects, like NSManagedObject, although in the library's xcode project the CoreData framework isn't added and it builds with no errors. However when I build my app it comes up with several errors such as:
Undefined symbols:
"_OBJC_CLASS_$_NSManagedObject", referenced from:
_OBJC_CLASS_$_AClass in library.a(AClass.o)
So seeing as all the errors mentioned CoreData objects, I added the CoreData framework to my app and it built successfully.
So now I tried remove CoreData framework from my app and added it the libraries project and them built both and it failed.
So why does it work when I have coredata added in my project but not in the libraries project, and only the library uses it?
(and why does the library build without needing the coredata framework on its own?)
The library is static. It is not a stand-alone piece of code, it must be linked.
Your application is linked, which means the linker resolves all the external dependencies and fills in the library functions' addresses in the final executable.
If you want to use a library that has a Core Data dependency in your application, you must link against Core Data.framework.
Adding a linking stage to a static library has no effect, since there is no linker involved in creating a static library, only a compiler (and an archiver).
Now, the problem can sometimes be avoided by using the new #import syntax in your libraries header file. The compiler will then automatically link against the used framework, even if you use a static library.

Copying dynamic library (.dylib) into a framework (.framework)

I have two XCode projects: a framework and a client application.
My application depends on my framework and everything works fine with that — the framework is being recompiled everytime the app is, the projects build paths are set correctly, it's completely okay.
Now the framework started using 3rd party dylib file, and it's linked against the dylib.
I've even added a build phase to copy that library into the framework's resources dir.
When i'm trying to run the application, everything compiles correctly, then i get this:
dyld: Library not loaded: /usr/local/lib/libplplot.9.dylib
Referenced from: /Users/railsmaniac/Projects/Study/Calculus of >approximations/Builds/Debug/XNMaths.framework/Versions/A/XNMaths
Reason: image not found
How can i fix it?
Adding the library into client application's resources doesn't fix the problem.
I can just place the library into the required location, but i prefer to keep it IN the framework.
Is it possible?
It looks like your application is expecting the library to be found at a specific path on the system. If you are on OS 10.5+ you can use the new #rpath functionality to allow your application to link dynamically to your library.
See this post for further details. It also shows the "old" way of doing this.