I have been reading framework tutorial as I need to separate UI and implementation by packaging implementation into framework. I am struggling to grab the concept.
For example I need to create a QR framework, when I click a button, it will launch the QR page > Catch the text string > Populate it into a label.
From the code in appCoda, how to I separate the UI? How's about the camera screen view(code in UI/Framework)?
Can frameworks include other frameworks?
Updated
I am trying to get my hands on the QR but merging the framework with the QR.
I am getting error:
NSBundle </var/mobile/Containers/Bundle/Application/5B97C76C-06E0-4E5A-821C-502477239962/UIControlDevApp.app/RWUIControls.bundle> (not yet loaded)
At this line
NSBundle *bundle = [NSBundle bundleWithURL:[[NSBundle mainBundle] URLForResource:#"RWUIControls" withExtension:#"bundle"]];
I have included my source code in here.
Hang in there and keep re-reading the tutorials. They are pretty meaty and take a bit of effort. Frameworks are great and worth the effort. Especially for something like the scanner that you will use again and again.
Yes frameworks can contain other frameworks and they can as well and....
When you create the framework you will end up with two output files. The framework itself as well as a bundle that contains your resources (this is the storyboard and image files.)
You will need to add both of these to the project you want to use them in.
First initialize an instance of your framework by referencing it whatever initializer you have created and supply the bundle name so it can find the resources.
In your framework you can use delegation to return the string that is decoded. Register the instance of your class in the main app (the one you just initialized) to receive delegate messages from your framework.
Finally push the view controller from your framework onto the stack for display within your main application.
self.qrScanner = [[QRScanner alloc] initWithBundleName:#"QRSCanner.bundle" navigationControllerRequired:NO];
self.qrScanner.delegate = self;
if ([self.delegate respondsToSelector:#selector(pushCustomViewController:)])
{
[self.delegate pushCustomViewController:self.qrScanner.qrScannerMainViewController];
}
This is is short code sample of what those three steps look like. Assuming you have created the framework and bundle this will allow you to reference them from your main application.
Related
I am working on a project with SwiftUI and it originally started with creating a new project as an "App" (Xcode, clicked on file, new, project, click on "App") but was then later asked to put it into a pod as a framework. I did it successfully (Xcode, clicked on file, new project, click on "Framework"), however I am unsure what the differences are and I'm unsure why I would want to do that. To me they look very similar, except that I'm unable to launch my project as a framework in the simulator. Luckily SwiftUI offers the canvas preview window however it is a bit finicky when it comes to certain button interactions, which is why I am wanting to use the simulator.
Two places of confusion:
What is the difference between an app and a framework project?
Why is it more advantageous to have my project as a framework?
An App is a standalone application that can be launched and run. For example, all of the apps that you have on your phone are just that -- apps. You tap on them and they launch and run, presenting a user interface, accepting input, etc.
A framework is something else entirely. It's a collection of code that is bundled together into a package that is used by another framework or by an app. Some frameworks are provided by the system -- for example, SwiftUI is a framework that it sounds like you're using in your app. Other frameworks are provided by 3rd parties. For example, you can find many frameworks via CocoaPods or the Swift Package Manager -- Alamofire is a common example. Also, you can make your own frameworks and use them in your own code as a form of organization and separation of responsibilities.
Why is it more advantageous to have my project as a framework?
It is not -- they are two almost completely different concepts (besides both ultimately being collections of code and resources). If you intend to build an app that is launch-able on someone's device, your only choice is to make an app. If you intend to make a collection of reusable code for use in your or someone else's app, than you would make a framework.
Excellent answer (and upvoted) by #jnpdx. Let me give you a physical example:
(1) Create a project in Xcode that is a framework. Call it "MyAppKit". Inside it create, well, basically anything - a View, UIView, or more likely a function that will be shared by several views. (Let's go with that.)
public func setLoginName(_ login:String) -> String {
return ""Hello, " + login + "!";
}
Pretty simple. Call it, pass in something, and it returns a string saying hello. Please note the public piece. It matters. (And there's much more there. This is a simple example.)
(2) Now we get to your app or apps. Let's say you have two apps that need to use this (again, very simple) code. One is SwiftUI, one is UIKit. (It doesn't matter except for syntax.) Sine my forte is UIKit I'll use that. (And it can be several dozen apps too.)
import MyAppKit
let myLoginMessage = setLoginName("World").
Pretty much, it's "Hello, World!'
Again, this is really a nonsensical example. But it should get you started on what the difference in Xcode is between a Framework project and an App project is.
This seems like a basic request, but I can't find the answer to it anywhere. I want to wrap some existing iOS code that I wrote, in a Appcelerator module. That's it. Important points:
I am NOT wrapping a pre-existing 3rd party iOS SDK.
I wrote the iOS code being wrapped.
Code is verified as working within xcode.
There are no .a files. There are 2x .h files and 2x .m files though.
There are no UI elements in the iOS code as it is only designed to connect the native bluetooth hardware to the app.
I have created a generic appcelerator iOS module project, built it, and successfully called the generic ID function within my app.
I cannot figure out how to successfully edit the generic module so that it utilizes my code. Every attempt results in it refusing to compile, and it's maddening.
I do not have access to Hyperloop.
Once I can successfully build the wrapped module, I would call an initialization function which triggers a native bluetooth hardware search. Once connected, there are functions within the module to send commands to the hardware and receive data back. This is the official documentation I've followed so far:
http://docs.appcelerator.com/platform/latest/#!/guide/iOS_Module_Quick_Start
That helped me build the blank module, include it in the app, and ensure that it worked by calling the built in test property. From there it stops short of actually telling me what I need to know. These are the closest things I've found so far, while still not being what I need:
http://docs.appcelerator.com/platform/latest/#!/guide/iOS_Module_Project-section-43288810_iOSModuleProject-AddaThird-PartyFramework
appcelerator module for existing ios project sdk
Heck, I still don't even know if I can do this within studio or if I have to edit the generic module in Xcode. Help! :) Many thanks in advance.
so first of all, this is not best practice and will cause possible problems in the future when the SDK changes and your module still relies on outdated core API's.
Regarding your question, you could either create a new component that subclasses the existing class, e.g.
class TiMyModuleListViewProxy : TiUiListViewProxy {
}
and call it with
var myList = MyModule.createListView();
or you write a category to extend the existing API with your own logic, e.g.
#interface TiUIListViewProxy (MyListView)
- (void)setSomethingElse:(id)value;
#end
#implementation TiUIListViewProxy (MyListView)
- (void)setSomethingElse:(id)value
{
// Set the value of "somethingElse" now
}
#end
I would prefer the second option since it matches a better Objective-C code-style, but please still be aware of the possible core-changes that might effect your implementation in the feature. Thanks!
I want to build a swift framework which can be added to hosting applications and run some logic
It basically show a new screen with web view which does some things (among other JS bridging)
After creating the logic as a regular app (with invocation button) i am now trying to convert it to a framework which can be added easily to existing projects
Is this the right way to do it? my code contain a ViewController which should be segue to
How do i start converting it to a framework? can a framework contain ViewControllers? how to test it? I see for example that a regular UIView dont exist is not available in the view adder
In an iOS or OS X Framework, which contains common code for both its App, and app Extensions, is there a way to detect if the code is being run under the main app, or one of its extensions? Specifically I'd like to detect if the framework is being used as part of a WatchKit extension as opposed to within the iPhone part of the App.
UIDevice.currentDevice always returns the iPhone as that is what is running the code. I believe I could check if WKInterfaceDevice exists, but that doesn't seem too elegant.
One option is to check the file extension of the current target. This has the advantage that it works in shared libraries and frameworks, whereas other options often only work within a target itself:
+ (BOOL) isAppExtension
{
return [[[NSBundle mainBundle] executablePath] containsString:#".appex/"];
}
This answer was informed by this question and answer. Those answers also outline how to set a preprocessor macro, which would be another good option in some cases, though that wouldn't be accessible from your framework.
I've not marked this question as a duplicate of that one, however, as these options are generic to all App extensions, neither is particularly elegant, and there may be WatchKit-specific options for what you're trying to achieve.
Specifically for WatchKit I came up with the following:
[[[NSBundle mainBundle] bundleIdentifier] hasSuffix:#"watchkitextension"];
Or in Swift:
NSBundle.mainBundle().bundleIdentifier?.hasSuffix("watchkitextension")
This relies on the fact that a WatchKit extension must have a bundle id ending in watchkitextension.
I am looking for a possibility of loading Obj C based source dynamically and show the view in my iOS application. For example: I have a set of code written for showing a view, i want to dynamically load this code and show this view.
Some thing like,
I'll have a service running in the background of my iOS app.
It will get a set of Obj C code from my server in text format
This dynamic Obj C code should get executed dynamically and show the respective iOS view
From Comments Not released in the appstore.. its for internal
Is this possible?
Short answer: No
Not so short answer:
You could—in theory—include either the C, or C++ interface to the Clang compiler toolchain in your project, have that library compile the code you download, and then (through either NSBundle or direct interaction with dlopen) link that compiled code into your app.
In practice, if what you want to achieve is submitting to the App Store, this is explicitly prohibited by the Terms and Conditions.
You can't do this for deployment to the app store.
You wouldn't use plain text for this, you'd use a bundle (NSBundle). A bundle can contain both file (graphics, NIBs) resources and code so you can create your view classes and any associated NIBs, compile the bundle and then store it on your server. The app can then download the bundle and load it at runtime.
You can do it for non-app store apps. I have not tried this approach.
From Apple Docs:
The key to loading code from an external bundle is finding an
appropriate entry point into the bundle’s executable file. As with
other plug-in schemes, this requires some coordination between the
application developer and the plug-in developer. You can publish a
custom API for bundles to implement or define a formal plug-in
interface. In either case, once you have an appropriate bundle or
plug-in, you use the NSBundle class (or the CFBundleRef opaque type)
to access the functions or classes implemented by the external code.
Loading Objective-C Classes If you are writing a Cocoa application,
you can load the code for an entire class using the methods of
NSBundle. The NSBundle methods for loading a class are for use with
Objective-C classes only and cannot be used to load classes written in
C++ or other object-oriented languages.