How to call web service written in objective c from swift file - ios

I have a webservice written in objective C. I want it access it from swift file. How do I achieve that? My attempt so far:
Webservice.h
#import <Foundation/Foundation.h>
typedef void(^WebServiceCompletionHandler)(id result,BOOL isError,NSString *strMsg);
#interface Webservice : NSObject
#property(strong,nonatomic) NSString *strURL;
-(void)registerWithFullName:(NSString*)strFullName ContactNumber:(NSString*)strContactNumber WithCompletionHandler:(WebServiceCompletionHandler)handler;
#end
Webservice.m
#implementation Webservice
-(id)init
{
if (self=[super init])
{
self.strURL=#"www.abc.com/registration";
}
return self;
}
-(void)registerWithFullName:(NSString*)strFullName ContactNumber:(NSString*)strContactNumber WithCompletionHandler:(WebServiceCompletionHandler)handler{
//Implementation
}
Now the swift file where I want to call the webservice.
Register.swift
override func viewDidLoad {
let service = Webservice.init()
heyWeb.registerWithfullName("Test", contactNumber: "+1039383838383", withCompletionHandler: { (result, isError, strMsg) -> Void in
})
}
But I am getting the following error while running the project.
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_Webservice", referenced from:
type metadata accessor for __ObjC.Webservice in Register.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Can anyone help me to figure out the problem?

create one bridge file with name -Bridging-Header.h and import your objc file in that bridge file, and finally Goto Project settings and give the path of that bridge file in Objective C Bridging Header as follows Sample-Bridging-Header.h

Related

iOS error: cannot find the symbol when linking in Swift

I have following code in Swift in A.swift file:
/// **A.swift**
protocol Johnkui: class {
var name: TruncatedView? { get set }
}
/// typealias TruncatedView = String
class TruncatedView: UIView {
}
extension UIView {
private struct TruncatedViewKey {
static var navigationViewKey = "navigationViewKey"
}
var name: TruncatedView? {
set {
objc_setAssociatedObject(self, &TruncatedViewKey.navigationViewKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_ASSIGN)
}
get {
return objc_getAssociatedObject(self, &TruncatedViewKey.navigationViewKey) as? TruncatedView
}
}
}
and B.swift file has following code:
/// B.swift
class JJ: UIView, Johnkui {
}
When compiling these two files, a linking error was reported:
Undefined symbols for architecture x86_64:
"__TFE9SwiftTestCSo6UIViewm4nameGSqCS_13TruncatedView_", referenced from:
__TTWC9SwiftTest2JJS_7JohnkuiS_FS1_m4nameGSqCS_13TruncatedView_ in ViewController.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
However, when combining these two files into one, the error is gone, and I cannot find out the reason for this result, what's your explanation?

Undefined symbols Swift.UnsafeMutableBufferPointer

After downloading Xcode 8 and migrating to Swift 3 I'm not longer able to archive the project. At the same time the project builds without any issues.
Error that I get:
Undefined symbols for architecture armv7:
"Swift.UnsafeMutableBufferPointer.(subscript.materializeForSet :
(Swift.Int) -> A).(closure #1)", referenced from:
function signature specialization of generic specialization
with
Swift.UnsafeMutableBufferPointer :
Swift.MutableCollection in Swift and
Swift.UnsafeMutableBufferPointer :
Swift.RandomAccessCollection in Swift> of Swift._siftDown (inout A,
index : A.Index, subRange : Swift.Range, by : inout
(A.Iterator.Element, A.Iterator.Element) -> Swift.Bool) -> () in
OrderCoordinator.o
function signature specialization of generic specialization
with
Swift.UnsafeMutableBufferPointer :
Swift.MutableCollection in Swift and
Swift.UnsafeMutableBufferPointer :
Swift.RandomAccessCollection in Swift> of Swift._heapSort (inout A,
subRange : Swift.Range, by : inout (A.Iterator.Element,
A.Iterator.Element) -> Swift.Bool) -> () in OrderCoordinator.o
function signature specialization of generic specialization
with
Swift.UnsafeMutableBufferPointer :
Swift.MutableCollection in Swift and
Swift.UnsafeMutableBufferPointer :
Swift.RandomAccessCollection in Swift> of Swift._partition (inout A,
subRange : Swift.Range, by : inout (A.Iterator.Element,
A.Iterator.Element) -> Swift.Bool) -> A.Index in OrderCoordinator.o
ld: symbol(s) not found for architecture armv7 clang: error: linker
command failed with exit code 1 (use -v to see invocation)
I was able to get rid of error by commenting array sorting code in following function:
func didFinishWithResults(_ results: [PhotoProcessorResult]) {
guard let album = albumService.currentAlbum else { return }
//let sortedResults = results.sorted(by: { $0.fileIndex < $1.fileIndex })
let updateItems = zip(sortedResults, album.assetItems).map { (photoProcessorResult, assetItem) -> UpdateItem in
UpdateItem(path: photoProcessorResult.filePath, position: photoProcessorResult.fileIndex, isCover: assetItem.isCover)
}
albumService.updateAlbumWithItems(updateItems) { (success, errorDescription) in
if success {
self.handleAlbumUpdate()
} else {
self.showFailureAlert(errorDescription) {
self.startProcessingAlbum(self.albumService.currentAlbum)
}
}
}
}
While I resolved issue by sorting data using NSArray, I don't like this solution.
Will be grateful for any suggestions.
Since it compiles i don't think there is anything wrong with your code. The fact that it says "Undefined symbols for architecture armv7" and is failing to archive tells me that something is going on with your project, but unfortunately there are many ways to cause this problem. arm7 is iphone 5 so your project is probably setup correctly only for arm64. Try the solutions mentioned here: Undefined symbols for architecture armv7
If here is problem only for the this line:
let sortedResults = results.sorted(by: { $0.fileIndex < $1.fileIndex })
You can change to it:
let sortedResults = results.sorted { (first, second) -> Bool in
return first.fileIndex < second.fileIndex
}
Did it solve your problem?
Issue disappeared after updating to XCode 8.1.
Thanks everyone :)

Linking error in unit test using URLRequestConvertible

I have a weird problem writing a simple unit test (Xcode 7.2) for a very simple function which makes sure a parameter is added to a URL:
func appendToken(token: String, toRequest request: URLRequestConvertible) throws -> URLRequestConvertible {
var error: NSError?
let modifiedRequest: NSMutableURLRequest
(modifiedRequest, error) = Alamofire.ParameterEncoding.URL.encode(request, parameters: ["token": self.token])
guard error == nil else {
// TODO: handle error
throw error!
}
return modifiedRequest
}
The unit test is like this:
func testTokenAddition() {
let token = "ABCD12345"
let client = MyClass(token: token)
let originalRequest = NSURLRequest(URL: NSURL(string:"http://localhost")!)
do {
let modifiedRequest = try client.appendToken(token, toRequest: originalRequest).URLRequest
XCTAssertTrue(modifiedRequest.URLRequest.URLString.hasSuffix("token=\(token)"))
} catch {
XCTFail()
print(error)
}
}
Obviously this is a very simple test on which I want to build upon (so please don't focus on the actual assertion). But when I try to run the test, I get this linking error:
Undefined symbols for architecture x86_64:
"protocol witness table for __ObjC.NSURLRequest : Alamofire.URLRequestConvertible in Alamofire", referenced from:
SDKitTests.SDKitTests.testTokenAddition (SDKitTests.SDKitTests)() -> () in SDKitTests.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
The function works when I run it from a normal target, so the problem is in the test function, but I'm not clear on how I should be calling it, I run the same code in a non-test class and there was no problem, so I'm a bit puzzled by this. Also the error message is a bit cryptic, from what I've Googled, a witness table is kind of like a vtable for protocols. But I haven't messed with that, the extension to NSMutableURLRequest is implemented in Alamofire, and I'm just using it.
What am I doing wrong? What do I need to do to fix it?
Ensure the Alamofire library is linked with your test target.
You may also need to remove inherit! :search_paths from the test target.

XCTest Array extension in swift

I wish to unit test my Array extension.
extension Array {
func itemPassingTest(test: (T) -> Bool) -> T? {
for item in self {
if test(item) {
return item
}
}
return nil
}
}
In my unit test target, I have
import XCTest
import JLTExample
class JLTExampleTests: XCTestCase {
func testExtensionArray() {
let target = [ ["a" : 1], ["a" : 2], ["a" : 3] ]
let actual = target.itemPassingTest { $0["a"] == 2 }
XCTAssertNotNil(actual)
}
}
When building I get the error
Undefined symbols for architecture i386:
"__TFSa15itemPassingTestU__fGSaQ__FFQSbGSqQ_", referenced from:
__TFC17JLTExampleTests17JLTExampleTests18testExtensionArrayfS0_FT_T_ in JLTExampleTests.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
My guess is I'm importing my extension, but I don't know how to import an extension. I was hoping that my extension would have been imported with the rest of my code in import JLTExample.

iOS undefined linker ld error

I wrote a simple function, passes the compiler but not the linker.
Any idea why?
- (BOOL) connectedToWifi
{
CFArrayRef myArray = CNCopySupportedInterfaces();
// Get the dictionary containing the captive network infomation
CFDictionaryRef captiveNtwrkDict = CNCopyCurrentNetworkInfo(CFArrayGetValueAtIndex(myArray, 0));
NSLog(#"Information of the network we're connected to: %#", captiveNtwrkDict);
NSDictionary *dict = (__bridge NSDictionary*) captiveNtwrkDict;
NSString* ssid = [dict objectForKey:#"SSID"];
if ([ssid rangeOfString:#"WXYZ"].location == NSNotFound || ssid == NULL)
{
return false;
}
else
{
return true;
}
}
This is the error I get:
Undefined symbols for architecture i386:
"_CNCopySupportedInterfaces", referenced from:
-[miApp_funcs connectedToWifi] in miApp_funcs.o
"_CNCopyCurrentNetworkInfo", referenced from:
-[miApp_funcs connectedToWifi] in miApp_funcs.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Following are steps-
1) Click project in Navigator area
2) Select 'TARGETS' tab
3) Click on 'Build Phases'
4) Select 'Link Binary With Libraries'
5) Then you can see '+' button at the bottom in the area.
You can now add the SystemConfiguration framework that you want.
#import <SystemConfiguration/SystemConfiguration.h>
You have to link to, and #import <SystemConfiguration/SystemConfiguration.h>, to have access to the Captive Network (CN) classes and functions.

Resources