7

I am trying to import this library in my Swift project. I am doing all step by step from this document and this answer, but nothing works.

Here is my screenshot: enter image description here

Here is my Bridging-Header.h:

//
//  Use this file to import your target's public headers that you would like to expose to Swift.
//

#import <UIKit/UIKit.h>

#import "VKUser.h"
#import "VKAccessToken.h"
#import "VKCache.h"
#import "VKStorage.h"
#import "VKStorageItem.h"
#import "VKRequestManager.h"
#import "VKRequest.h"
#import "VKConnector.h"
#import "VKMethods.h"

#import "NSData+toBase64.h"
#import "NSString+Utilities.h"

The important thing is that I have VKConnector class and VKConnectorDelegate protocol in one file. Maybe thats the problem?

//
// Copyright (c) 2013 Andrew Shmig
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "VKMethods.h"
#import "VKAccessToken.h"
#import "VKStorage.h"
#import "NSString+Utilities.h"
#import "VKStorageItem.h"


@class VKConnector;


static NSString *const kVKErrorDomain = @"kVkontakteErrorDomain";


typedef enum
{
    kVKApplicationWasDeletedErrorCode
} kVkontakteErrorCode;


/** Protocol incapsulates methods that are triggered during user authorization
 process or access token status changes.
 */
@protocol VKConnectorDelegate <NSObject>

@optional
/**
 @name Show/hide web view
 */
/** Method is called when user needs to perform some action (enter login and
password, authorize your application etc)

@param connector VKConnector instance that sends notifications
@param webView UIWebView that displays authorization page
*/
- (void)VKConnector:(VKConnector *)connector
    willShowWebView:(UIWebView *)webView;

/** Method is called when UIWebView should be hidden, this method is called after
user has entered login+password or has authorized an application (or pressed
cancel button etc).

@param connector VKConnector instance that sends notifications
@param webView UIWebView that displays authorization page and needs to be hidden
*/
- (void)VKConnector:(VKConnector *)connector
    willHideWebView:(UIWebView *)webView;

/**
@name UIWebView started/finished loading a frame
*/
/** Method is called when UIWebView starts loading a frame

@param connector VKConnector instance that sends notifications
@param webView UIWebView that displays authorization page
*/
- (void)VKConnector:(VKConnector *)connector
webViewDidStartLoad:(UIWebView *)webView;

/** Method is called when UIWebView finishes loading a frame

@param connector VKConnector instance that sends notifications
@param webView UIWebView that displays authorization page
*/
- (void) VKConnector:(VKConnector *)connector
webViewDidFinishLoad:(UIWebView *)webView;

/**
 @name Access token
 */
/** Method is called when access token is successfully updated

@param connector VKConnector instance that sends notifications
@param accessToken updated access token
*/
- (void)        VKConnector:(VKConnector *)connector
accessTokenRenewalSucceeded:(VKAccessToken *)accessToken;

/** Method is called when access token failed to be updated. The main reason
could be that user denied/canceled to authorize your application.

@param connector VKConnector instance that sends notifications
@param accessToken access token (equals to nil)
*/
- (void)     VKConnector:(VKConnector *)connector
accessTokenRenewalFailed:(VKAccessToken *)accessToken;

/**
 @name Connection & Parsing
 */
/** Method is called when connection error occurred during authorization process.

@param connector VKConnector instance that sends notifications
@param error error description
*/
- (void)VKConnector:(VKConnector *)connector
    connectionError:(NSError *)error;

/** Method is called if VK application was deleted.

@param connector VKConnector instance that sends notifications
@param error error description
*/
- (void)  VKConnector:(VKConnector *)connector
applicationWasDeleted:(NSError *)error;

@end


/** The main purpose of this class is to process user authorization and obtain
access token which then will be used to perform requests from behalf of current
user.

Example:

    [[VKConnector sharedInstance] startWithAppID:@"12345567"
                                  permissions:@[@"wall"]
                                  webView:webView
                                  delegate:self];
*/
@interface VKConnector : NSObject <UIWebViewDelegate>

/**
@name Properties
*/
/** Delegate
 */
@property (nonatomic, weak, readonly) id <VKConnectorDelegate> delegate;

/** Application's unique identifier
*/
@property (nonatomic, strong, readonly) NSString *appID;

/** Permissions
*/
@property (nonatomic, strong, readonly) NSArray *permissions;

/**
@name Class methods
*/
/** Returns shared instances of VKConnector class.
*/
+ (id)sharedInstance;

/**
@name User authorization
*/
/** Starts user authorization process.

@param appID application's unique identifier
@param permissions array of permissions (wall, friends, audio, video etc)
@param webView UIWebView which will be used to display VK authorization page
@param delegate delegate which will receive notifications
*/
- (void)startWithAppID:(NSString *)appID
            permissons:(NSArray *)permissions
               webView:(UIWebView *)webView
              delegate:(id <VKConnectorDelegate>)delegate;

/**
@name Cookies
*/
/** Removes all cookies which were obtained after user has authorized VK
application. This method is used to log out current user.
*/
- (void)clearCookies;

@end

I have tried to split VKConnector header file into two - VKConnector class and VKConnectorDelegate, but that didn't work.

What am I doing wrong?

Community
  • 1
  • 1
AndrewShmig
  • 4,843
  • 6
  • 39
  • 68
  • Did you imported required headers (VkontakteSDK.h) to the swift bridging header? – Anil Varghese Jul 08 '14 at 09:12
  • Check the bridging header. – CW0007007 Jul 08 '14 at 09:20
  • @Anil, yes, I have imported VkontakteSDK.h but it didn't work, after that I have tried to import all header files which were imported in VkontakteSDK.h header file - nothing... – AndrewShmig Jul 08 '14 at 10:10
  • Specifically look up bridging header. Doesn't sound like you have set it up right also watch the WWDC session on swift & Objective C – AppHandwerker Jul 08 '14 at 12:23
  • @iosDevSi, whats wrong with my bridging header? I am doing all step by step from Apple Docs, what more should be done? – AndrewShmig Jul 08 '14 at 12:33
  • 1
    Entirely unrelated to this question, but you should drop your base64 library in favor of [Apple's base64 methods](https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/Reference/Reference.html#//apple_ref/occ/instm/NSData/base64EncodedDataWithOptions:), now that they've been made public. – Kevin Jul 13 '14 at 00:07

4 Answers4

11

Your delegate function name is VKConnector and you also have a class named VKConnector. That's your conflict. In Objective C your delegate method is VKConnector:withBool: but in Swift it's simply VKConnector and withBool is not a part of the name.

If you follow Cocoa patterns, your delegate method should be called - (void) connector:(VKConnector *)connector withBool:(BOOL)boolean;

Malloc
  • 15,434
  • 34
  • 105
  • 192
Essan Parto
  • 703
  • 11
  • 18
  • but I am not using any other framework except UIKit and Foundation. Why than it work in ObjC project, but not in Swift project? – AndrewShmig Jul 12 '14 at 15:07
  • ok, lets assume that i don't have source codes of some library. how the hell I can use ObjC code written as I shown you (in test project and SDK) in Swift project? Thank you for your help, it really makes sense. Need to think about it. – AndrewShmig Jul 12 '14 at 20:38
  • 1
    Well, the idea behind that convention of naming delegate methods is that an object is doing something not a class. You won't see something like `UITableView:numberOfRowsInSection:` because `numberOfRowsInSection` is something that an instance of `UITableView` will respond to not the class and so the method is `tableView:numberofRowsInSection:`. – Essan Parto Jul 12 '14 at 20:59
  • I think that if you don't have the source of the library and have this problem, maybe you can create an objective c class for use the delegate and use this class in swift like a "bridge" – anthonyqz Dec 30 '15 at 15:46
  • That was exactly my problem. Thanks for helping! – ThorstenC Jan 02 '16 at 10:54
6

Did XCode create your bridging header file or did you create the file by yourself?

If you created the bridging header file yourself, make sure that build settings point to your file:

enter image description here

mic
  • 907
  • 6
  • 17
  • Please, read again my question. There are two links: from docs and from SO, and definitely I have added that setting in my project (by myself and by XCode also) – AndrewShmig Jul 09 '14 at 19:11
  • You reminded me I need to add an import to my bridging file - solved :) – OhadM Jan 16 '18 at 10:31
1

The "undeclared type" error in a mixed project is nearly always solved as I have explained here:

https://stackoverflow.com/a/24216718/341994

Basically, wherever you are importing the automatically generated "...-Swift.h" header file into your Objective-C code, you will need to import "VKConnector.h" into that file as well, earlier in the list of imports.

This is counterintuitive and annoying, but it solves the problem, and in fact is actually documented if you look very closely.

Community
  • 1
  • 1
matt
  • 515,959
  • 87
  • 875
  • 1,141
  • thank you, but it doesn't work :( I have even created this topic on Apple Dev forum: https://devforums.apple.com/message/1002447 and test project ( https://yadi.sk/d/QxPhrnysWFDGt ) where you can see that it's not working. – AndrewShmig Jul 11 '14 at 19:46
1

If it helps anyone, on our project this issue was caused because we had a bridging header on the main project target and a bridging header on an extension target.

Our extension target was using a class defined in our main project. This class was defined inside the extension bridging header and was working for the majority of our classes.

However when we gave target membership of one of our classes to the main project target we were getting this error in that single file. The fix was to ensure the files used were in both bridging header files.

treeba
  • 469
  • 5
  • 10
  • I have the same situation, two target and trying to import my Objective-C project in to another target which is Swift classes. can you explain it more, maybe it will fix my problem.. – Maryam Fekri Nov 22 '17 at 19:53