No known class method for selector 'indexPathForRow:inSection:' - ios

I'm trying to import/use this project in my Swift application, but the compiler throws tons of error with following message:
No known class method for selector 'indexPathForRow:inSection:'
Following is the typical code which generates the above error:
if ([self tileForIndexPath:[NSIndexPath indexPathForRow:row inSection:i]].empty) {
...
}
I can able to run the downloaded project as an standalone application without having any problem, though.
I've also added all the frameworks to my main application - those were used and installed to the said project, but that didn't help. My main project's deployment target is 10.0.

indexPathForRow:inSection: is a static constructor method that creates NSIndexPath instances. It is defined in UIKit:
https://developer.apple.com/documentation/foundation/nsindexpath/1614934-indexpathforrow?language=objc
In this project the author imports UIKit in the pch file:
https://github.com/austinzheng/iOS-2048/blob/7c0840a0f7bd77b01d6a36778a253f8f4b2e6529/NumberTileGame/NumberTileGame/NumberTileGame-Prefix.pch#L14
So you have 2 options: either setup a pch file for Objective-C code in your project (create the file and add to Xcode project build settings), or in each source file where you get this error add #import <UIKit/UIKit.h>.

Related

Installing third party Objective-C library within Swift 3 / Xcode 8 (SharkORM)

Im pretty new to Xcode/Swift and want to install a third party library(SharkORM).
I drag'n'dropped the folder "SharkORM" into XCode and selected "Create groups". Then i created a file "Swift-Bridging-Header.h" and typed in #include “SharkORM.h” as described in the documentation. When i hold CMD and click on it it leads me to the interface declaration(good!?). Now when i try to use it: class MyClass: SRKObject { ... } i get an error: "Use of undeclared type 'SRKObject'". But i can CMD+click on it which leads me to the interface declaration again.
I tried to install with Cocoapod, too, with no success.
As posted on GitHub, it sounds like the header file you created has not been added to the build settings as the chosen bridging header.
That is the most likely scenario leading to the object not being defined in your swift code.
Check, if SharkORM.h contains SRKObject declaration. If not, find header file with it and place it to bridging header too

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

Unable to integrate ZXingObjC in a iOS Swift Project

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.

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.

Unit testing a static library with RestKit

I'm attempting to follow along with the RestKit unit test guide ( https://github.com/RestKit/RestKit/wiki/Unit-Testing-with-RestKit ) except that my project is a static library instead of an app.
Here is the test I've written:
- (void)testMappingOfDate
{
id parsedJSON = [RKTestFixture parsedObjectWithContentsOfFixture:#"plan.json"];
RKMappingTest *test = [RKMappingTest testForMapping:[self planMapping] object:parsedJSON];
[test expectMappingFromKeyPath:#"plan.date" toKeyPath:#"date"];
STAssertNoThrow([test verify], nil);
}
When I attempt to run the test I receive this error on the first line of the test:
error: testMappingOfDate (api_clientTests) failed: -[NSBundle parsedObjectWithContentsOfResource:withExtension:]: unrecognized selector sent to instance 0x1765c40
It seems like its not finding the NSBundle category defined by RestKit, but my test target header search path is set to "$(BUILT_PRODUCTS_DIR)/../../Headers" and I've verified this path includes NSBundle+RKAdditions.h which contains the supposed "unrecognized selector".
Is there something I'm missing here?
You are trying to include a category within your binary that comes from a library. To get that accomplished you will need to add the following to your (Unit-Test-Target's) build settings.
Other Linker Flags: -ObjC
From Apple's QA:
Objective-C does not define linker symbols for each function (or
method, in Objective-C) - instead, linker symbols are only generated
for each class. If you extend a pre-existing class with categories,
the linker does not know to associate the object code of the core
class implementation and the category implementation. This prevents
objects created in the resulting application from responding to a
selector that is defined in the category.
Solution:
To resolve this issue, the static library should pass the -ObjC option
to the linker. This flag causes the linker to load every object file
in the library that defines an Objective-C class or category. While
this option will typically result in a larger executable (due to
additional object code loaded into the application), it will allow the
successful creation of effective Objective-C static libraries that
contain categories on existing classes.
The error means that the "unrecognized selector" issue is at runtime. The compiler and NSBundle+RKAdditions.h do not give this error they would at compile timr.
The issue is that the code that has #implementation NSBundle(RKAdditions) is not linked into your app. So you need to add this to your build

Resources