How to add integrate code from Github into your existing project - ios

I want to get the device location in the application that I want to develop. I have created a SWIFT project and I want to add the code here
https://github.com/intuit/LocationManager
into my existing swift project.
So here it says
Manually from GitHub
Download all the files in the INTULocationManager subdirectory.
Add the source files to your Xcode project (drag and drop is easiest).
Import the INTULocationManager.h to your bridging header.
Swift: Add #import "INTULocationManager.h" to your bridging header.
So basically can I just drag the source code to my project?
Also how do I create the bridging header?
then let say how do I use it in my ViewController?
Thanks

Maybe you should consider using CocoaPods as it may be easier for you to integrate, and in the long-run, is easier to update.
To answer your specific question about a manual installation:
Yes, you can just drag the source code into your project. Instructions for creating the bridging header can be found on the internet (for example, here).
Next, as the instructions say, add #import "INTULocationManager.h" to your bridging header, e.g:
#ifndef TestBridgingHeader_Bridging_Header_h
#define TestBridgingHeader_Bridging_Header_h
#import "INTULocationManager.h"
#endif /* TestBridgingHeader_Bridging_Header_h */
To use the library, you have to translate the example given on the Github page from Objective-C to Swift.
let locMgr = INTULocationManager.sharedInstance()
locMgr.requestLocationWithDesiredAccuracy(INTULocationAccuracy.City, timeout: 10, block: { currentLocation, achievedAccuracy, status in
if status == .Success {
} else if status == .TimedOut {
} else {
}
})
This is made easier by remembering a few rules:
Method calls in Obj-C are called via enclosing square brackets (e.g. [INTULocationManager sharedInstance]) while in Swift they use dot-syntax (e.g. INTULocationManager.sharedInstance())
Enums such as INTULocationAccuracyCity generally get translated to only their last part (.City in this case). Swift infers that .City is equivalent to INTULocationAccuracy.City.
Obj-C blocks such as INTULocationRequestBlock are equivalent to Swift closures of the same type.

Related

How to call Objective C viewcontroller in Swift

I found a ViewController SDK using objective C. I want to use it swift but fail to call.
Can you suggest me any idea for using it?
I want to create a storyboard and set the custom class in ViewControllerObjectiveC, but still fail to open the viewcontroller.
let vc = sb.instantiateViewController(withIdentifier: "ViewControllerObjectiveC") as! ViewControllerObjectiveC
self.dismiss(animated: false, completion: nil)
self.presentingViewController?.present(vc, animated: false, completion: nil)
In order to interact Obj-C code with Swift you will need to have a bridging header file. The name of the bridging header MUST be like <YourProject>-Bridging-Header.h. While you can create it manually there is an option which the Xcode creates it yourself. For the second option create a new file with .m extension. The Xcode will ask you to create a bridging header. Approve it.
Now import everything in this file you need to reach from Swift. In your case put the following inside your bridging header:
#import "ViewControllerObjectiveC.h"
Assuming your Obj-C file has the name ViewControllerObjectiveC.h. The code you shared should work now.
Bridging Header is the way to solve your problem.
See this Apple Document:
https://developer.apple.com/documentation/swift/imported_c_and_objective-c_apis/importing_objective-c_into_swift
Step 1
Drag and drop your Objective-C files into the project after that you will see this message inside your Xcode project.
See this popup
Then click on Create Bridging header option. It will create one header file inside your project.
Confirm Header File
Now you just have to Import your Objective C File into created header file.
That's It.

iOS Swift project, have Objective-C file and I want to import a swift class to the Objective-C file [duplicate]

I have written a library in Swift and I wasn't able to import it to my current project, written in Objective-C.
Are there any ways to import it?
#import "SCLAlertView.swift" - 'SCLAlertView.swift' file not found
You need to import ProductName-Swift.h. Note that it's the product name - the other answers make the mistake of using the class name.
This single file is an autogenerated header that defines Objective-C interfaces for all Swift classes in your project that are either annotated with #objc or inherit from NSObject.
Considerations:
If your product name contains spaces, replace them with underscores (e.g. My Project becomes My_Project-Swift.h)
If your target is a framework, you need to import <ProductName/ProductName-Swift.h>
Make sure your Swift file is member of the target
Here's what to do:
Create a new Project in Objective-C
Create a new .swift file
 
A popup window will appear and ask "Would You like to configure an Objective-C bridging Header".
Choose Yes.
Click on your Xcode Project file
Click on Build Settings
Find the Search bar and search for Defines Module.
Change value to Yes.
Search Product Module Name.
Change the value to the name of your project.
In App delegate, add the following : #import "YourProjectName-Swift.h"
Note: Whenever you want to use your Swift file you must be import following line :
#import "YourProjectName-Swift.h"
Instructions from the Apple website:
To import Swift code into Objective-C from the same framework
Under Build Settings, in Packaging, make sure the Defines Module
setting for that framework target is set to Yes. Import the Swift code
from that framework target into any Objective-C .m file within that
framework target using this syntax and substituting the appropriate
names:
#import "ProductName-Swift.h"
Revision:
You can only import "ProductName-Swift.h" in .m files.
The Swift files in your target will be visible in Objective-C .m files
containing this import statement.
To avoid cyclical references, don’t import Swift into an Objective-C
header file. Instead, you can forward declare a Swift class to use it
in an Objective-C header. Note that you cannot subclass a Swift class
in Objective-C.
If you're using Cocoapods and trying to use a Swift pod in an ObjC project you can simply do the following:
#import <FrameworkName>;
Go to build settings in your project file and search for "Objective-C Generated Interface Header Name. The value of that property is the name that you should include.
If your "Product Module Name" property (the one that the above property depends on by default) varies depending on whether you compile for test/debug/release/etc (like it does in my case), then make this property independent of that variation by setting a custom name.
Importing Swift file inside Objective-c can cause this error, if it doesn't import properly.
NOTE: You don't have to import Swift files externally, you just have to import one file which takes care of swift files.
When you Created/Copied Swift file inside Objective-C project. It would've created a bridging header automatically.
Check Objective-C Generated Interface Header Name at Targets -> Build Settings.
Based on above, I will import KJExpandable-Swift.h as it is.
Your's will be TargetName-Swift.h, Where TargetName differs based on your project name or another target your might have added and running on it.
As below my target is KJExpandable, so it's KJExpandable-Swift.h
First Step:-
Select Project Target -> Build Setting -> Search('Define') -> Define Module
update value No to Yes
"Defines Module": YES.
"Always Embed Swift Standard Libraries" : YES.
"Install Objective-C Compatibility Header" : YES.
Second Step:-
Add Swift file Class in Objective C ".h" File as below
#import <UIKit/UIKit.h>
#class TestViewController(Swift File);
#interface TestViewController(Objective C File) : UIViewController
#end
Import 'ProjectName(Your Project Name)-Swift.h' in Objective C ".m" file
//TestViewController.m
#import "TestViewController.h"
/*import ProjectName-Swift.h file to access Swift file here*/
#import "ProjectName-Swift.h"
If you have a project created in Swift 4 and then added Objective-C files, do it like this:
#objcMembers
public class MyModel: NSObject {
var someFlag = false
func doSomething() {
print("doing something")
}
}
Reference: https://useyourloaf.com/blog/objc-warnings-upgrading-to-swift-4/
There's one caveat if you're importing Swift code into your Objective-C files within the same framework. You have to do it with specifying the framework name and angle brackets:
#import <MyFramework/MyFramework-Swift.h>
MyFramework here is the "Product Module Name" build setting (PRODUCT_NAME = MyFramework).
Simply adding #import "MyFramework-Swift.h" won't work. If you check the built products directory (before such an #import is added, so you've had at least one successful build with some Swift code in the target), then you should still see the file MyFramework-Swift.h in the Headers directory.
Be careful with dashes and underscores, they can be mixed up and your Project Name and Target name won't be the same as SWIFT_MODULE_NAME.
Checkout the pre-release notes about Swift and Objective C in the same project
https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html#//apple_ref/doc/uid/TP40014216-CH10-XID_75
You should be importing
#import "SCLAlertView-Swift.h"
Search for "Objective-C Generated Interface Header Name" in the Build Settings of the target you're trying to build (let's say it's MyApp-Swift.h), and import the value of this setting (#import "MyApp-Swift.h") in the source file where you're trying to access your Swift APIs.
The default value for this field is $(SWIFT_MODULE_NAME)-Swift.h. You can see it if you double-click in the value field of the "Objective-C Generated Interface Header Name" setting.
Also, if you have dashes in your module name (let's say it's My-App), then in the $(SWIFT_MODULE_NAME) all dashes will be replaced with underscores. So then you'll have to add #import "My_App-Swift.h".
If you want to use Swift file into Objective-C class, so from Xcode 8 onwards you can follow below steps:
If you have created the project in Objective-C:
Create new Swift file
Xcode will automatically prompt for Bridge-Header file
Generate it
Import "ProjectName-Swift.h" in your Objective-C controller (import in implementation not in interface) (if your project has space in between name so use underscore "Project_Name-Swift.h")
You will be able to access your Objective-C class in Swift.
Compile it and if it will generate linker error like: compiled with newer version of Swift language (3.0) than previous files (2.0) for architecture x86_64 or armv 7
Make one more change in your
Xcode -> Project -> Target -> Build Settings -> Use Legacy Swift Language Version -> Yes
Build and Run.
#import <TargetName-Swift.h>
you will see when you enter from keyboard #import < and after automaticly Xcode will advice to you.
only some tips about syntax, about Xcode everything has been said
you cannot import 'pure" functions, only classes, even if marked "public", so:
public func f1(){
print("f1");
}
will NOT be called in ANY way.
If You write classes., add inheritance from NSObject, other will NOT be usable.
if it inherits from NSObject, as below:
class Utils : NSObject{
static func aaa()->String{
return "AAA"
}
#objc static func bbb()->String{
return "BBB"
}
#objc private static func ccc()->String{
return "CCC"
}
}
in OBJC:
aaa() NOT called: "No known class method for selector 'aaa'"
bbb() ok
ccc() NOT called: "No known class method for selector 'aaa'"
Find the .PCH file inside the project. and then add #import "YourProjectName-Swift.h" This will import the class headers. So that you don't have to import into specific file.
#ifndef __IPHONE_3_0
#warning "This project uses features only available in iPhone SDK 3.0 and later."
#endif
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "YourProjectName-Swift.h"
#endif

What is missing after Bridging Obj-C to Swift

I have done this before, normally without trouble, setting the bridging header, etc.
This time, I tried to import a Obj-C framwork (github.com/jensmeder/FSKModem/) into my swift project. When typing code I can "see" all the Obj-C methods.
But when I compile the code, I get errors like "Use of undeclared identifier 'delete'" or "Use of undeclared identifier 'new'". Example of code in a .m file that is giving the error:
_audioFormat = new AudioStreamBasicDescription();
I'm familiar with Swift and don't know about Obj-C but I guess "delete" or "new" should exist, right? Do they belong to some framework that I should add?
I can compile the original code in Obj-C without trouble, but I need to incorporate it in my project that is written in Swift.
Many thanks for any help
Some more information...
The following functions are inside the .m file. Do you know why the "new" and "delete" keywords are unrecognized? This works fine when compiled as a normal "Obj-C" project. The error appears in Swift project only (after bridging headers of course):
-(void)dealloc
{
[self disconnect:NULL];
if (_audioFormat)
{
delete _audioFormat;
}
}
-(void) setupAudioFormat
{
_audioFormat = new AudioStreamBasicDescription();
//...
}
Should I add some #include that I might be missing, besides Foundation?
new and delete are C++ keywords; you can use them in C++ files (usually .cpp or .cc) and in Objective-C++ files (always .mm). You cannot use them in Swift (.swift) or in Objective-C (.m) files.
It is perfectly valid to use an Objective-C class from an Objective-C++ file from Swift; you can use Objective-C to wrap C++ classes for Swift usage. However it is not valid to use C++ from plain Objective-C.
Quite probably you just need to rename your Objective-C file to .mm.
new and delete are keywords from C++ not from Swift or Objective-C.
Swift
let audioFormat = AudioStreamBasicDescription()
Objective-C
AudioStreamBasicDescription* audioFormat = [[AudioStreamBasicDescription alloc] init];
In Swift, you simply need to call the object initializer when creating an object.
_audioFormat = AudioStreamBasicDescription()
The new keyword is an Objective-C combo of alloc and init.

How to import swift file into objective-c file in a swift project

The situation is a little complicated. I have a Swift project, and I have imported some Objective-C files into this project. Now, I want to use some Swift classes in these Objective-C files. How to do that?
It seems this reference covers everything:
https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html
Specifically:
Importing Swift into Objective-C
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". (You’ll learn more
about the product module name later, in Naming Your Product Module.)
Example:
Foo.swift in product named ExampleProduct
#objc public class Bar: NSObject {
var x: Int = 3
}
Blah.m in same product:
#import <Foundation/Foundation.h>
#import <ExampleProduct-Swift.h>
void doStuff() {
Bar *y = [[Bar alloc] init];
printf("%ld\n", (long)y.x);
}
It's even easy to call doStuff() from a Swift file if you create an Objective-C header file that defines the function prototype and then import that header file in the bridging header.
There's no limit to jumping back and forth.
Based on the comments it looks like you're having trouble importing the reverse bridging header.
Try this in terminal to ensure you're naming the file correctly:
% cd ~/Library/Developer/Xcode; find . -name '*-Swift.h'
I get (scroll all the way to the right):
./DerivedData/ExampleProduct-avoxifngmebkkqgndldocildsfcm/Build/Intermediates/ExampleProduct.build/Debug-iphonesimulator/ExampleProduct.build/DerivedSources/ExampleProduct-Swift.h
./DerivedData/ExampleProduct-avoxifngmebkkqgndldocildsfcm/Build/Intermediates/ExampleProduct.build/Debug-iphonesimulator/ExampleProduct.build/Objects-normal/x86_64/ExampleProduct-Swift.h
./DerivedData/ExampleProduct-avoxifngmebkkqgndldocildsfcm/Build/Intermediates/ExampleProduct.build/Debug-iphonesimulator/ExampleProductTests.build/DerivedSources/ExampleProductTests-Swift.h
./DerivedData/ExampleProduct-avoxifngmebkkqgndldocildsfcm/Build/Intermediates/ExampleProduct.build/Debug-iphonesimulator/ExampleProductTests.build/Objects-normal/x86_64/ExampleProductTests-Swift.h
Also, potentially a dup of:
How to call Objective-C code from Swift
With 326 upvotes that's worth studying!

Using Dropbox, or any third party, framework in Swift class

I'm trying to write a swift class that uses the Dropbox Sync API, but can't get swift to see the framework. The objective C in my project can use the Dropbox framework successfully. I have a bridging header that seems to be properly set up in the project settings and references <Dropbox/Dropbox.h>. But in my swift file it is as if I have done nothing.
This objective C code in my project works and is what I am trying to replicate in Swift:
#import <Dropbox/Dropbox.h>
...
if ([DBAccountManager sharedManager].linkedAccount == nil) {
[[DBAccountManager sharedManager] linkFromController:self];
[[DBAccountManager sharedManager] addObserver:self block:^(DBAccount *account) {
DBFilesystem *fileSystem = [[DBFilesystem alloc] initWithAccount:account];
[DBFilesystem setSharedFilesystem:fileSystem];
}];
As I said, I have <Dropbox/Dropbox.h> in the bridging header that Xcode automatically created for me. However this swift code fails to compile with the error 'Use of unresolved identifier 'DBAccountManager''
import UIKit
class PiecesListTableViewController : UITableViewController {
override func loadView() {
super.loadView()
// This fails with unresolved identifier 'DBAccountManager'
let accountManager = DBAccountManager.sharedManager
// As does this
let accountManagerNew = DBAccountManager(appKey:"", secret:"")
}
}
Any thoughts on how to get my swift code to be able to see the Dropbox framework?
I didn't manage to solve this. Instead I worked around it by abstracting all use of the Dropbox framework into objective C classes and using those in my swift code.
Actually I found the way to do it:
Create a dummy .m file so that XCode will ask you to create a bridging header, then delete the .m
Under project Build settings, add DropboxSDK.framework under Link Binary with Libraries
Open the bridging-header file and write in it #import <DropboxSDK/DropboxSDK.h>
XCode won't compile your code, and SourceKit Service will likely crash every time you'll open up a Swift file.
That's because of two errors in the Dropbox SDK (at least for a Swift environment):
Open the DropboxSDK.framework you linked before in Finder, then navigate to Headers folder
Open the file DBQuota.h and add #import <Foundation/Foundation.h> before #interface
Open the file DBSession+iOS.h and add #import <UIKit/UIKit.h> before #interface
Now you can use Dropbox SDK classes in your Swift files.
This will save you from creating an Objective-C wrapper on each class.

Resources