Unable to integrate ZXingObjC in a iOS Swift Project - ios

Im working on an iOS project, which shows the customer number in a barcode. I had installed the framework ZXingObjC with CocoaPods, described in GitHub.
I can compile my Project without errors. I can also use the classes of ZXingObjC in my Objective-C classes, without errors. After than, I have added the import Command #import <ZXingObjC/ZXingObjC.h> to my bridging header file, like my other custom objective-c classes, without compile errors. (I had testet the header file by destroying some import statements and got the expected file not found exception.)
But now, I can't use any class of ZXingObjC in my swift classes. I only got the following compile error: Use of undeclared type '...'. The Xcode autocomplete is not working, too.
e.g.
var test : ZXMultiFormatWriter?
>> Use of undeclared type 'ZXMultiFormatWriter'
I tried:
setup new project, same issue
checked header search path: $(SRCROOT)/Pods/Headers/Public/Adjust
reinstalled the ZXingObjC framework
checked build settings: Enable Modules: YES
checked build settings: Other Linker Flags: $(inherited) -ObjC
-framework "ZXingObjC"
checked linked binaries in the build phases: framework is added
checked import statement in the bridging header file (#import
<ZXingObjC/ZXingObjC.h> and #import "ZXingObjC/ZXingObjC.h" -- no
difference)
Windows style: restarting Xcode and Mac ;-)
I'm using:
Xcode: 6.3.2
CocoaPods: 0.37.2
Project Deployment target: iOS 8.0
SDK: 8.3
Does anyone know the problem? Can anyone help?
How can I make the ZXingObjC framework available in swift?

Actually it is an easy issue:
Podfile
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!
pod 'ZXingObjC', '~> 3.1'
So, on terminal:
cd workspace
pod install
Then, once opened project on Xcode, you have to edit bridging-header adding ZXingObj:
#import <ZXingObjC/ZXingObjC.h>
Finally, in your swift classes that uses ZXingObjC, you have to import ZXingObjC.
import ZXingObjC
class ZXingObjCWrapper {
func encode() {
let writer = ZXMultiFormatWriter.writer()
....
}
}

The rest of the code for when you need to set an UIImage with this bar code:
func generateDataMatrixQRCode(from string: String) -> UIImage? {
do {
let writer = ZXMultiFormatWriter()
let hints = ZXEncodeHints() as ZXEncodeHints
let result = try writer.encode(string, format: kBarcodeFormatDataMatrix, width: 1000, height: 1000, hints: hints)
if let imageRef = ZXImage.init(matrix: result) {
if let image = imageRef.cgimage {
return UIImage.init(cgImage: image)
}
}
}
catch {
print(error)
}
return nil
}

The header search path was not correct in my project. The right values are:
$(inherited)
"${PODS_ROOT}/Headers/Public"
"${PODS_ROOT}/Headers/Public/ZXingObjC"
The second and third lines were not added by installation with CocoaPods.
EDIT: The installed framework have to be added to "Embedded Binaries" in General tab of the project.

I tried everything on this page to add ZXingObjC as a Pod. My goal was to generate an Aztec barcode.
I checked my Header Search Path. As Reddas said, I had to manually add "${PODS_ROOT}/Headers/Public/ZXingObjC". I also added ZXingObjC as an Embedded Binary (in the General Tab).
I checked my bridging file & all was good. I checked my view controllers where I wanted to generate the barcode. The import ZXingObjC was there.
No compile errors. But I can't declare a variable of ZXingObjC.
No luck. Any more suggestions?
EDIT - I went into the Targets, Build Settings and searched for Header Search Paths. I added in BOTH "${PODS_ROOT}/Headers/Public/ZXingObjC" and "${PODS_ROOT}/Headers/Private/ZXingObjC"
This seemed to unclog whatever broke. It works now. Strangely, I can now even delete those entries and it works.

Related

Failed to recognize AWSDynamoDB with XCode 7.0 Beta, iOS 8.3, and aws-ios-sdk-2.2.0

I am matching guides for using AWSDynamoDB in a test project using Swift 2 in XCode 7.0 Beta. I am required to use that platform instead of the previous stable one and make it work.
I am using the next links:
https://docs.aws.amazon.com/mobile/sdkforios/developerguide/setup.html
http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LoadData_Java.html
Best way to make Amazon AWS DynamoDB queries using Swift?
I already made it work for reading and writing text files and images to an S3 Bucket, but now that I am trying to use DynamoDB service something might be missing.
Here is my Podfile contents:
# Uncomment this line to define a global platform for your project
platform :ios, '8.3'
target 'AWSSDKTest' do
source 'https://github.com/CocoaPods/Specs.git'
pod 'AWSCore'
pod 'AWSAutoScaling'
pod 'AWSCloudWatch'
pod 'AWSDynamoDB'
pod 'AWSEC2'
pod 'AWSElasticLoadBalancing'
pod 'AWSKinesis'
pod 'AWSLambda'
pod 'AWSMachineLearning'
pod 'AWSMobileAnalytics'
pod 'AWSS3'
pod 'AWSSES'
pod 'AWSSimpleDB'
pod 'AWSSNS'
pod 'AWSSQS'
pod 'AWSCognito'
end
target 'AWSSDKTestTests' do
end
I had to delete Podfile.lock and Pods folder, deleted Configuration Sets in Project->Info->Configurations, and installed pods again.
Here is my bridging.h file:
#ifndef AWSSDKTest_bridging_h
#define AWSSDKTest_bridging_h
#endif
#import <AWSCore/AWSCore.h>
#import <AWSS3/AWSS3.h>
#import <AWSDynamoDB/AWSDynamoDB.h>
#import <AWSSQS/AWSSQS.h>
#import <AWSSNS/AWSSNS.h>
#import <AWSCognito/AWSCognito.h>
I downloaded the aws-ios-sdk-2.2.0.zip file, unzipped and added to Frameworks all the AWS frameworks.
I am trying to use AWSDynamoDBModel, here is a swift file for implementing the Upload Sample Items Example for using DynamoDB Mapper:
import Foundation
class Forum : AWSDynamoDBModel, AWSDynamoDBModeling {
var name : String = ""
var category : String = ""
var threads : Int = 0
var messages : Int = 0
var views : Int = 0
// override init!() { super.init() }
required init!(coder: NSCoder!) {
fatalError("init(coder:) has not been implemented")
}
class func dynamoDBTableName() -> String! {
return "Demo"
}
class func hashKeyAttribute() -> String! {
return "email"
}
class func rangeKeyAttribute() -> String! {
return "date"
}
/*
override init(dictionary dictionaryValue: [NSObject : AnyObject]!, error: NSErrorPointer) {
super.init(dictionary: dictionaryValue, error: error)
}
override func isEqual(anObject: AnyObject?) -> Bool {
return super.isEqual(anObject)
}
*/
}
I had to comment the lines that caused error because those might be fixed. The errors mentioned that those functions couldnt be overridden and that super.init couldnt be called inside a root method.
After cleaning and building again, the error is at the class declaration line
class Forum : AWSDynamoDBModel, AWSDynamoDBModeling {
The error says: Use of undeclared type 'AWSDynamoDBModel'
If I try writing other AWSDynamoDB classes they don't appear in the list of suggestions and then cause the same error.
Additionally I want to mention that in the developer's guide setup (first link above) the 4th point of the Getting Started with Swift section says: "Import the AWSCore header in the application delegate":
#import <AWSCore/AWSCore.h>
Than can't be done, only in the bridging.h file which is mentioned in the 2nd point.
My first request of assistance is in fixing the error mentioned and making the project recognize the AWSDynamoDB framework.
Then I request your help for any observation about this merge of different tutorials, also any other online tutorial or guide that is more clear than those mentioned.
In case you are using CocoaPods (0.36) with "use_frameworks!", this answer might solve your problem:
"Normally when you’re importing Objective-C code into Swift, you do so by including the header of the file containing that code in the “Bridging Header” for your project. And that is indeed how you include code from a static library (which your pods used to be.)
But it is not how your import Objective-C code from a Framework. To do that you simply type…
import Framework
…inside your Swift file that’s using the Objective-C class (where “Framework” is the name of the actual Framework containing the class.)"
Source here: http://rogueleaderr.com/post/115372471213/unresolved-identifier-in-swift-when-importing
I think the problem is not related to Xcode7Beta, but the installation process of your project. (My sample DynamoDB project runs fine under Xcode7Beta.)
If you installed the AWS Mobile SDK via cocoapods, you neither have to worry about the bridging file nor need to download aws-ios-sdk-2.2.0.zip file since cocoapods already did everything for you.
My suggestion would be:
clean your project, remove all aws related frameworks, bridging files that you manually added,delete Podfile.lock and Pods folder and AWSSDKTest.xcworkspace file, and the re integrate pods by running "pod install"
Open your project using Xcode 6.4, confirm it can be built and run successfully under Xcode 6.
If everything looks good via Xcode 6, reopen it via Xcode7Beta, If it failed to compile, please post the error output so I can take a look.
Thanks

How to import and use SDWebImage in swift xcode 6.3.1

Im new to Swift and now making a project that includes showing many photos from the web and I understand that I need to use SDWebImage.
I saw related questions here and in other places but all are in Objective-C syntax and not working for me.
What I did till now:
I downloaded the zip from GitHub
Copied SDWebImage folder to my folder
Tried all possible combinations for import
#import <"SDWebImage/UIImageView+WebCache.h">
import SDWebImage/UIImageView+WebCache.h
etc..
Can someone please help me import it
Firstly, you need configure Bridging Header, it is described here at SO. Use the following:
#import <SDWebImage/UIImageView+WebCache.h>
This will import Objective-C code to Swift code
Secondly, just use it, like:
self.imageView.sd_setImageWithURL(self.imageURL)
As far as I understood you already have a Bridging header and only need to organize your imports. Since you copied the source files directly into your project without using cocoapods or Carthage you do the import like this:
#import "UIImageView+WebCache.h"
Swift 3.0 code
import SDWebImage
let url = URL.init(string: "https://vignette3.wikia.nocookie.net/zelda/images/b/b1/Link_%28SSB_3DS_%26_Wii_U%29.png")
imagelogo.sd_setImage(with: url , placeholderImage: nil)
In swift 5.1 simply import the SdWebimage and use extenion
extension UIImageView{
func downloadImage(url : String, placeHolder : UIImage?) throws{
if let url = URL(string: url){
self.sd_imageIndicator?.startAnimatingIndicator()
self.sd_setImage(with: url) { (image, err, type, url) in
if err != nil{
self.sd_imageIndicator?.stopAnimatingIndicator()
print("Failed to download image")
}
self.sd_imageIndicator?.stopAnimatingIndicator()
}
}
}
}
The only way it worked for me (using mac os 10.11.4 and ios 9.3) was this:
download and unpack framework from link: https://github.com/rs/SDWebImage/releases/download/3.6/SDWebImage-3.6.framework.zip:
drag that framework into x-code project and check option: Copy items if needed (In project navigator you should now see suitcase icon containing a folder with .h files)
create new bridging header file: cmd+n -> file -> new -> file... and select "header" template icon
open that file, write line (just above #endif:) #import < SDWebImage/UIImageView+WebCache.h > (this is path of one of header files from framework)
the most important step from #Azat answer above, is to connect the file you just made with project, in build settings:
select project name (blue icon in Project navigator)
select "Build Settings" on your right start to type "Bridging header..." and when you have row containing "Objective-C Bridging header"
press twice in empty field in that row (window pops-up), and drag bridging header file from Project navigator into that window.
hopefully now you can use library methods as: imageView.setImageWithUrl(url, placeholderImage:)

No autocomplete on cocapods for AppCode 3.1

I have recently set up a project from a base XCode Project with the cocoapods installation, and when importing the project into AppCode 3.1, I am not getting any autocompletion for my swift frameworks that are installed through CocoaPods
Here is my Podfile
# Uncomment this line to define a global platform for your project
platform :osx, '10.10'
use_frameworks!
target 'Main' do
pod "SwiftyJSON", ">= 2.1.3"
pod 'BrightFutures', '~> 1.0.0-beta.3'
end
target 'MainTests' do
end
As you can see, I have 2 pods defined (one is SwiftyJson and one is BrightFutures). Both of these pods are installed as Swift Frameworks (hence why use_frameworks!) is there.
Everything appears to be imported and working correctly for AppCode (I have two projects, one is the main project, and the other one is Pods, which is the exact same as it is in XCode), however it appears that AppCode doesn't index any of the Pod frameworks, so I am not getting autocompletion status on using those frameworks, at all. As an example, in the following code
import Cocoa
import BrightFutures
#NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(aNotification: NSNotification) {
let f = future { 5 }.map{f in f + 7}
f.onSuccess{callback in println(callback)}
// Insert code here to initialize your application
}
func applicationWillTerminate(aNotification: NSNotification) {
// Insert code here to tear down your application
}
}
I get no autocompletion on the following
import BrightFutures (importing anything else that isn't from CocoaPods works fine)
Auto complete on anything on this line let f = future { 5 }.map{f in f + 7} or this one f.onSuccess{callback in println(callback)}
Autocomplete works fine on anything else (i.e. aNotification) which is an argument on the applicationDidFinishLaunching function
Is there some setting in AppCode that I am missing, or is this something that hasn't been implemented yet? In XCode, autocompletion works completely correctly.
EDIT: I have also noticed that in AppCode, the .framework files are in red (not sure if this means anything?)

Using an Obj-C sub-project in a Swift application

My team has a few full Obj-C libraries we like te reuse in our projects. To do so, we usually set up a git submodule, and then add it to the xcode project as a sub-project (Using target dependency, link binary with library and updating the User Header Search Paths)
So far it's only been done in full Obj-C projects, and I'm now trying to use it in a Swift project but with very little success so far. I tried to add the briding-header file, referenced it in the project and filled it like so :
#import "MyLibraryHeader.h"
With the target header being in the User Header Search Paths.
It lets me build, but when using it in my Swift files:
let test = MyLib();
let secondTest = MyLib.classMethod1("some_arguments");
I get an EXC_BAD_INSTRUCTION on secondTest, and the following logs in the debugger:
(lldb) po test
error: <EXPR>:1:1: error: use of unresolved identifier 'test'
(lldb) po secondTest
error: Error in auto-import:
failed to get module 'MyProject' from AST context:
/Users/siegele/Sources/MyProject_iOS/MyProject/Classes/MyProject-Bridging-Header.h:12:9: error: 'MyLibraryHeader.h' file not found
#import "MyLibraryHeader.h"
^
failed to import bridging header '/Users/siegele/Sources/MyProject_iOS/MyProject/Classes/MyProject-Bridging-Header.h'
Found the following question with no answer : Xcode 6 crashing when using Objective-C subproject inside Swift
Any help would be appreciated.
I followed the HockeyApp tutorial that can be found here:
http://support.hockeyapp.net/kb/client-integration-ios-mac-os-x/integrate-hockeyapp-for-ios-as-a-subproject
In the end, I was on the right tracks but messed up the Header Search Paths:
Add subproject xcodeproj to the workspace
On the main project : Link binary with library, and add the subproject product library (Bonus points : add it as a target dependency too)
Update Header Search Paths (not User Header Search Paths) accordingly
Import your Library.h in the main project Bridging-Header.h file
What threw me off for a while is that the Swift Compiler setting for the Objective-C Bridging Header was not set automatically. Check the Build Settings for your target and ensure the "Objective-C Bridging Header" setting is not blank.

Install Realm in a Swift App

I am trying to add Realm to my app written in swift. I have followed the tutorial and I can't seem to get it to work. The biggest problem is that when I try to import Realm I get No such module 'Realm' I don't know what else to try. You can see my efforts below.
You can see the instructions here: http://realm.io/docs/cocoa/0.85.0/#swft
I have also copied the instructions below:
Due to the current lack of proper infrastructure for Swift dependency management, using Realm in your project requires the following steps:
Add Realm as a submodule by opening the Terminal, cd-ing into your top-level project directory, and entering the command git submodule add git#github.com:realm/realm-cocoa.git
Open the realm-cocoa folder, and drag Realm.xcodeproj into the file navigator of your Xcode project.
In Xcode, navigate to the target configuration window by clicking on the blue project icon, and selecting the application target under the “Targets” section in the sidebar.
In the tab bar at the top of that window, open the “Build Phases” panel.
Expand the “Target Dependencies” gorup, and add Realm’s iOS framework.
Expand the “Link Binary with Libraries” group, and add Realm’s iOS framework as well as libc++.dylib.
Click on the + button at the top left of the panel and select “New Copy Files Phase”. Rename this new phase to “Copy Frameworks”, set the “Destination” to “Frameworks”, and add Realm.framework.
Drag the file at realm-cocoa/Realm/Swift/RLMSupport.swift into the file navigator of your Xcode project, unchecking the “Copy items if needed” checkbox.
Below is what it looks like in my project:
I am not sure exactly why this isn't working, but here is a workaround:
Follow the latest instructions.
Create a bridging header, for example by
Add a new Objective-C class to your xcode project.
Agree to have a bridging header created
Delete the Objective-C class
Add this in the bridging header:
#import "Realm/Realm.h"
Remove any Import Realm statements from your code, including from RLMSupport.swift
Now it should work. For example, I test with putting this in my ViewController.swift
import UIKit
class Person: RLMObject {
dynamic var name = ""
dynamic var birthdate = NSDate(timeIntervalSince1970: 1)
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let author = Person()
author.name = "David Foster Wallace"
// Get the default Realm
let realm = RLMRealm.defaultRealm()
// Add to the Realm inside a transaction
realm.beginWriteTransaction()
realm.addObject(author)
realm.commitWriteTransaction()
// Print all Persons
println(Person.allObjects())
}
}
Which prints:
RLMArray <0x7a243760> (
[0] Person {
name = David Foster Wallace;
birthdate = 1970-01-01 00:00:01 +0000;
}
)
I have been talking with the guys at Realm, and it turns out that the latest instructions don't work with Realm <= 0.85 They changed they way the build the framework and it won't work anymore. They said they will release 0.86 later today that should fix the problems anyone is having with Swift. In the meantime I have a test project that anyone can take the latest framework from. https://github.com/smitt04/testRealm
Version 0.86 is now out and this is no longer an issue.
The Swift installation instructions were long and convoluted, so I'm not surprised you and several other users ran into issues.
Please follow the latest installation instructions here.

Resources