How to recognize touch inside SVG object in Swift? - objective-c

I'm currently building an app where I need to recognize a touch point inside a SVG map. So I have a map with multiple rectangles and when the user touches one of these rectangles an action needs to be triggered. How can I solve this?
One option would be to mathematically calculate if the touch location lies in between a rectangle, but I am not a math genius.
My preferred option would be to use a framework. I found the SVGKit framework but unfortunately its written in Objective C.

You can use SVGKit for a Swift project. You have to use an umbrella header file, it is the 'master' header file for a framework.
Importing Objective-C into Swift
Access classes and other declarations from your Objective-C code in
Swift.
Overview
You can use Objective-C and Swift files together in a single project,
no matter which language the project used originally. This makes
creating mixed-language app and framework targets as straightforward
as creating an app or framework target written in a single language.
The process for using your Objective-C declarations from your Swift
code within mixed-language targets differs slightly depending on
whether you’re writing an app or a framework. Both processes are
described below.
Import Code Within an App Target
To import a set of Objective-C files into Swift code within the same
app target, you rely on an Objective-C bridging header file to expose
those files to Swift. Xcode offers to create this header when you add
a Swift file to an existing Objective-C app, or an Objective-C file to
an existing Swift app.
If you accept, Xcode creates the bridging header file along with the
file you were creating, and names it by using your product module name
followed by "-Bridging-Header.h". Alternatively, you can create a
bridging header yourself by choosing File > New > File >
[operating system] > Source > Header File.
Edit the bridging header to expose your Objective-C code to your Swift
code:
In your Objective-C bridging header, import every Objective-C header you want to expose to Swift.
In Build Settings, in Swift Compiler - Code Generation, make sure the Objective-C Bridging Header build setting has a path to the
bridging header file. The path should be relative to your project,
similar to the way your Info.plist path is specified in Build
Settings. In most cases, you won't need to modify this setting.
Any public Objective-C headers listed in the bridging header are
visible to Swift. The Objective-C declarations are automatically
available from any Swift file within that target, with no import
statements. Use classes and other declarations from your custom
Objective-C code with the same Swift syntax you use for system
classes.
Import Code Within a Framework Target
To use the Objective-C declarations in files in the same framework
target as your Swift code, you’ll need to import those files into the
Objective-C umbrella header—the master header for your framework.
Import your Objective-C files by configuring the umbrella header:
Under Build Settings, in Packaging, make sure the Defines Module setting for the framework target is set to Yes.
In the umbrella header, import every Objective-C header you want to expose to Swift.
Swift sees every header you expose publicly in your umbrella header.
The contents of the Objective-C files in that framework are
automatically available from any Swift file within that framework
target, with no import statements. Use classes and other declarations
from your Objective-C code with the same Swift syntax you use for
system classes.
Source
Additional information
How to include Objective-C frameworks in your Swift project

Related

Problem with using Swift in Objective-C target

I have an old Objective-C project, which has multiple targets, and some of the targets share a framework (let's call it CJDataKit) that's also written in Objective-C. I'm trying to add some Swift code to my project, at least to the main app target, and have some limited implementation of it working, but I'm running into some issues whenever the Swift code needs to use or import the CJDataKit framework, or any header file that itself imports the CJDataKit framework.
What's Working
I wrote a basic UIView subclass in Swift (which didn't need any other code from my app), and I can use this in my Objective-C target, using #objc keyword and by importing "MyApp-Swift.h" in my Objective-C code.
I then wrote a new UIViewController subclass in Swift, and used a couple of simple Objective-C objects from both CJDataKit framework and non-framework classes. I did this by creating a bridging header file, and added the Objective-C headers there.
So far so good, and everything compiles fine.
What's Not Working
The problem happens if I try to import into Swift other Objective-C
files that might be importing the CJDataKit framework inside it. For
e.g. I wanted to write a Swift extension of an existing
UIViewController subclass (call is PageAViewController). This
subclass has imported multiple other header files. If I add it to the
bridging header file, I start getting build errors:
Include of non-modular header inside framework module 'CJDataKit':
'.../CJDataKit/Person.h'
Commenting out the #import CJDataKit makes it work for this particular file, but it still gets compile errors from a different header file (that was imported by PageAViewController). It'll only work if all the files imported don't have a #import CJDataKit, which is difficult and cumbersome. BTW, these files all belong to the app target, not the framework. So something about Swift doesn't like interacting with the CJDataKit framework directly, even though it works fine if it's built independently in the same app target along with the CJDataKit framework.
I've also tried importing the CJDataKit.h header file into the Swift
bridging header file, figuring this way I don't have to individually
import each file from the framework, but that doesn't work either.
That results in a different error:
Could not build module 'CJDataKit.h'
I've tried using #import <CJDataKit/CJDataKit.h> as well but same result.
From my settings:
- "Allow Non-modular Includes In Framework Modules" is Yes on the target, and framework. It is No at the project-level.
- "Defines Module" is also set to Yes, on both the app target and framework, and No at project-level.
Would love some help in getting this setup correctly. I've been searching for a solution, but haven't really found anything.

How to force `Xcode-generated header` ... in a Swift Project (Call Swift from Obj-C)

Xcode does not generate this -Swift.h header file when the project is a Swift project. The documentation says:
When you import Swift code into Objective-C, you rely on an
Xcode-generated header file to expose those files to Objective-C. This
automatically generated file is an Objective-C header that declares
the Swift interfaces in your target. It can be thought of as an
umbrella header for your Swift code. The name of this header is your
product module name followed by adding "-Swift.h".
If I try to include the -Swift.h file anyway, it says file not found.
I've been able to generate this file before in an Objective-C project.
But I want to call Swift from Objective-C, in a Swift project.
How do I call Swift from Obj-C in a Swift project?
Thanks!
If the Objective-C file in which you import *-Swift.h is in the same Swift target that contains the Swift code you are trying to use in Objective-C, you should have no trouble importing it. To make sure you are using the correct name, check the Objective-C Generated Interface Header Name under Build Settings. If the target is a framework, you may need to import the -Swift.h header a little differently:
#import "YourFrameworkModuleName/YourFrameworkModuleName-Swift.h"
whereas in an application target you would just do
#import "YourAppModuleName-Swift.h"
This is something I found from my experience.

how to use Objective-C project in my Swift project

Note: I know How to call Objective-C code from Swift, but I don't know below,
I want to use this EsptouchForIOS's Demo in my project. The demo is write in OC, it has a storyboard and controller. I want to know how to integrate the demo in my swift project, and use that storyboard and it's controller in my swift project.
I'll start writing from the very beginning. Suppose you have a project in Objective-C and now you want to continue your project's development in Swift. Follow the below guidelines: (This intends to your specific needs)
First choose to add a new file from File->New->File. In this process select your language as Swift. In the final step here, you will be prompted to Create Bridging Header. Select that:
Now build your project once (⌘+B). You may get an error like this:
Change your target's minimum deployment to the version that Swift supports. (Example in the below screenshot)
To use Objective-C resources in Swift files:
Now that you've got one ProjectName-Bridging-Header.h file in your project. If you want to use any Objective-C class in your Swift files, you just include the header file of that class in this bridging header file. Like in this project, you have ESP_NetUtil and ESPViewController class and their header files too. You want to expose them to Swift and use them later in Swift code. So import them in this bridging header file:
Build once again. Now you can go to your Swift file. And use the Objective-C classes as like you use any resource in swift. See:
N.B: You must expose all the class headers (that you're intending to use later in Swift) in that bridging header file
To use Swift resources in Objective-C files:
Now you may wonder, I've successfully used Objective-C resources in Swift. What about the opposite? Yes! You can do the opposite too. Find your Target->Build Settings->Swift Compiler - General->Objective-C Generated Interface Header Name. This is the header file you will be using inside your Objective-C classes for any Swift to Objective-C interoperability. To know more check here.
Now inside any of your Objective-C class, import that interface header and use Swift resources in Objective-C code:
You will get more understanding from the official apple documentation.
You can checkout the worked out version of your linked project here with Objective-C-Swift interoperability.
So according to your question, you have added an objective C bridge in your swift project using How to call Objective-C code from Swift.
Now, import all headers (.h) files of your objective-c source code (demo project) that you want to direct use in swift file.
For example, your demo project has EsptouchForIOS following header (file with extension .h) files in project source code.
ESPAppDelegate.h, ESPDataCode.h, ESPTouchDelegate.h
import a header file in your bridge, which you want to use in your swift code. Suppose in your swift code you want touch delegate ESPTouchDelegate then write,
#import "ESPTouchDelegate.h"
Here is snapshot of your demo integration in my Test Swift project with bridge
and import statements.
Now, there is function/method in an objective C file getValue
which is used/accessed in swift project/file.
Similarly, you can import as many files (source headers) as you want in bridge and use the same files (source code) in swift.
I have never tried to use objective-c from swift project. But I normally used swift classes from my objective-c project. I usually follow this instructions https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html from apple developer website.

Using Obj-C class extension in Swift?

I added some Obj-C code (the excellent Expressions) to my Swift project using Xcode's Add files... but it did not ask me if I wanted to make a bridging header. So I made one myself in the Obj-C code's group, edited it to #import the single header I needed, and made sure that file was referenced in the Swift Compiler in Build Settings. I then looked through the Obj-C code and made sure the .m files were in the target - they were, and they're listed in Compile Sources.
The header in question contains this:
#interface NSNumber (Expression)
+ (NSNumber *)numberByParsingExpression:(NSString *)expression;
+ (NSNumber *)numberByParsingExpression:(NSString *)expression withVariables:(NSDictionary *)varDictionary;
#end
Now I am trying to call this code using the same basic syntax as this post:
let result = NSNumber.numberByParsingExpression(f.1)
along with several variations on the theme. But it won't compile, "Type 'NSNumber' has no member 'numberByParsingExpression'".
Did I miss a step here?
According to https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html
You can create a bridging header yourself by choosing File > New >
File > (iOS, watchOS, tvOS, or OS X) > Source > Header File.
You’ll need to edit the bridging header file to expose your
Objective-C code to your Swift code.
In your Objective-C bridging header file, import every Objective-C
header you want to expose to Swift. For example:
In Build Settings, in Swift Compiler - Code Generation, make sure the
Objective-C Bridging Header build setting under has a path to the
bridging header file. The path should be relative to your project,
similar to the way your Info.plist path is specified in Build
Settings. In most cases, you should not need to modify this setting.
Any public Objective-C headers listed in this bridging header file
will be visible to Swift. The Objective-C functionality will be
available in any Swift file within that target automatically, without
any import statements. Use your custom Objective-C code with the same
Swift syntax you use with system classes.
If you already did this correctly, and it still isn't working, try deleting the projects derived data, and clean building your project.
Ok, this turns out to be an Xcode peccadillo.
When you create the header file within the group, it actually places it physically in the source folder. So in my case the header was created in /project/subproject/.h although it appeared within Xcode to be part of the base folder, /project/.h.
So in fact there were two headers, one in the right place with nothing in it, and another in the wrong place that was the one that was being edited within Xcode. So you have to look at the file inspector to make sure it placed the bridging header in the right place!

How do you prepare an Objective-C framework for Swift use?

I have an existing framework & bundle written in Objective-C and would like to access it in Swift.
How would I go about doing that?
Here's what I got:
1) Attempting to import the ObjC framework. Notice that I'm not successful.
Within the Objective-C framework project... attempting to make it usable for Swift.
I set the 'Defines Module' to YES:
I setup the bridge header within the ObjC framework app:
Yet I'm unable to access the framework. Apparently Xcode 6.1.1 doesn't convert the Objective-C to an importable Swift framework interface.
What am I missing?
Firstly, make sure your objective-c code is up to date
Then you add your objective-c code to your project, xcode will automatically ask you if you want to create a bridging header.
In your bridging header file, you just need to include your objective-c header files
example:
#import MyClass.h
save your header, and after that, you can test by trying to use your objective-c classes inside your swift code base