Iphone 导入sqlite3.h错误:框架模块内包含非模块头

Iphone 导入sqlite3.h错误:框架模块内包含非模块头,iphone,database,swift,sqlite,frameworks,Iphone,Database,Swift,Sqlite,Frameworks,我正在为我的应用程序创建一个自定义后端框架,它封装了我所有与数据库相关的逻辑,因此,当我们要使用任何数据库操作时,我们只需要调用该框架函数 现在,对于数据库操作,我需要将#导入名为Data.swift的文件中,其中包含我的所有数据库函数。但这是swift文件,所以如何导入sqlite 当我使用桥接头.h时,我收到错误消息 error: using bridging headers with framework targets is unsupported 桥接头.h在其内部有#import,并

我正在为我的应用程序创建一个自定义后端框架,它封装了我所有与数据库相关的逻辑,因此,当我们要使用任何数据库操作时,我们只需要调用该框架函数

现在,对于数据库操作,我需要将#导入名为Data.swift的文件中,其中包含我的所有数据库函数。但这是swift文件,所以如何导入sqlite

当我使用桥接头.h时,我收到错误消息

error: using bridging headers with framework targets is unsupported
桥接头.h在其内部有
#import
,并设置桥接头变量的设置

如果我在伞形标题中添加import语句,则会出现错误

include of non-modular header inside framework module
我在谷歌上搜索了很多,但找不到正确的答案。我也正确地观察和遵循了它,但我认为我仍然错过了一些东西


请给我一些建议。

据我所知,您不能直接将Objective-C文件导入框架中的Swift。但是你可以在同一个框架中的另一个Objective-C类中实现。因此,如果在框架中编写Objective-C类,就可以将头文件直接包含到类中并使用它

出于同样的目的,我最终在Objective-C中为
sqlite.h
编写了一个包装类,然后在我的Swift代码中访问它。您编写的包装类的标题必须公开并添加到您的伞形标题中

我写了这样的东西:

#ifndef SqlWrapper_h
#define SqlWrapper_h

struct sqlite3;

BOOL OpenDatabaseWithFileName(NSString* databaseFileName, struct sqlite3** database);

BOOL PrepareStatement(struct sqlite3* database,NSString *selectStatement,struct sqlite3_stmt** preparedStatement);

BOOL StepStatement(struct sqlite3_stmt* compiledStatement);

BOOL FinalizeStatement(struct sqlite3_stmt* compiledStatement);

NSInteger NumberOfRowsAffected(struct sqlite3* database);

NSInteger LastInsertedRowID(struct sqlite3* database);

NSInteger GetColumnCount(struct sqlite3_stmt* compiledStatement);

const unsigned char* GetColumnValue(struct sqlite3_stmt* compiledStatement,int index);

NSInteger GetColumnValueInInteger(struct sqlite3_stmt* compiledStatement,int index);

double GetColumnValueInDouble(struct sqlite3_stmt* compiledStatement,int index);

BOOL CloseDatabase(struct sqlite3* database);

#endif

这些函数中的每一个都包装了sqlite3方法。这些可以从同一框架中的Swift类中调用。

我已经获取了一个目标c文件,并对其进行了一些定制

Sqlite3Wrapper.h

#ifndef SqliteWrap_Sqlite3Wrapper_h
#define SqliteWrap_Sqlite3Wrapper_h

struct sqlite3;
@class SqlStatement;

@interface Sqlite3Wrapper : NSObject

-(id)initWithFileName: (NSString*) databaseFileName;

-(BOOL) openDatabase;

-(BOOL) closeDatabase;

-(BOOL) isOpen;

-(BOOL) executeStatement: (NSString*) sqlStatement;

-(SqlStatement*) prepareStatement: (NSString*) sqlStatement;

@end

#endif
Sqlite3Wrapper.m

#import <Foundation/Foundation.h>
#import <sqlite3.h>

#import "Sqlite3Wrapper.h"
#import "SqlStatement.h"

@implementation Sqlite3Wrapper {
    sqlite3* _database;
    NSString* _databaseFileName;
}

-(id) initWithFileName:(NSString *)databaseFileName {
    self = [super init];
    if (self) {
        _databaseFileName = databaseFileName;
    }
    return self;
}

-(BOOL) openDatabase {
    int returnValue = sqlite3_open([_databaseFileName UTF8String], &_database);
    if (returnValue == SQLITE_OK) {
        return YES;
    }

    return NO;
}

-(BOOL) closeDatabase {
    if (_database) {
        if (sqlite3_close(_database) == SQLITE_OK) {
            _database = nil;
            return YES;
        }
    }
    return NO;
}

-(BOOL) isOpen {
    return (_database != nil);
}

-(BOOL) executeStatement: (NSString *)sqlStatement {
    if (_database == nil) {
        return NO;
    }

    return (sqlite3_exec(_database, [sqlStatement UTF8String], nil, nil, nil) == SQLITE_OK);

//    sqlite3_stmt* statement;
//    if (sqlite3_prepare_v2(_database, [sqlStatement UTF8String], -1, &statement, nil) == SQLITE_OK) {
//        BOOL success = (sqlite3_step(statement) == SQLITE_OK);
//        sqlite3_finalize(statement);
//        return success;
//    }
//    return NO;
}

-(SqlStatement*) prepareStatement:(NSString *)sqlStatement {
    if (_database == nil) {
        return nil;
    }

    sqlite3_stmt* pStmt = nil;
    if (sqlite3_prepare_v2(_database, [sqlStatement UTF8String], -1, &pStmt, nil) == SQLITE_OK) {
        return [[SqlStatement alloc] initWithStatement: pStmt];
    }

    return nil;
}


@end
最后两个函数
createDatabase
logMessage
只是临时的,用于测试我是否可以直接访问这些函数

我已经为设备和模拟器的通用框架创建了一个“聚合目标”。但是当我使用这个通用框架时,我无法
导入记录器
,并收到错误“没有这样的模块‘记录器’”。但当我为设备打包框架并尝试添加相同的框架时,我就能够完成导入工作

最后,问题是,一旦我导入记录器,我就无法从框架中访问任何函数或数据。我只能访问用Objective C编写的
Sqlite3Wrapper
。我想使用该数据类或公共函数


如果您认为我做错了什么,请告诉我。

但我想将我的数据库逻辑编码到Swift中,并想公开这些Swift函数。如果我为此创建包装器,那么它可能会在目标C中结束所有函数的实现。您能在这里提供一些说明吗?这对我不起作用。它给了我一个错误,比如“错误:无法构建Objective-C模块”。你的解释让我从头文件复制了所有的功能原型。如果我使用4到5个SDK,那么我是否需要从这些SDK复制所有头文件?我认为这不是一个好的选择。我同意你的看法,这不是一个好的选择,但我恐怕,目前这似乎是唯一的选择。我建议不要为每个单独的方法编写转发函数,而是为功能编写包装器。请查看我的项目,目前尚未完成,但我完成了您试图实现的目标。您是否能够找到更好的方法来解决您的问题?如果是,请告诉我们。@Abdullah您能检查一下并告诉我是否有任何解决方案吗?您是否将
Logger.swift
和包含
数据的文件作为公共类。还导入框架,即导入
而不是类。我已经将Logger.swift和Data和Logger类都设置为公共类。我只导入该框架名称。我已经在dropbox上发布了我的代码,您可以通过链接访问这两个代码。框架:,测试项目:集成在“TestProduct”中的是聚合框架,它给出错误“没有这样的模块‘记录器’”。我用目标设备创建的框架已放置在上,该框架允许“导入记录器”,但不允许访问记录器和数据类中的任何方法。不幸的是,我现在几天没有访问mac的权限,因此无法对此进行测试。您找到解决方案了吗?我在这里遇到了同样的问题,请检查我在最后评论中发布的代码。我提供了下载代码的链接。或者检查我在下面写的答案,其中包含我为解决此问题而创建的文件的代码。基本思想是,我必须创建SQLWrapper类并#在侧伞头中导入“SQLWrapper.h”。检查下面的代码,您将得到一些解决方案。但我仍然面临一些问题,比如,当我在示例代码中导入框架时,它不起作用。我认为阿卜杜拉是回答我的框架相关问题的最佳人选
import Foundation

public class Logger {
    var dbWrapper:Sqlite3Wrapper
    var dataAccess = [String:AnyObject]()

    public init(dbName:String) {
        let docDirPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString
        let dbPath:NSString = docDirPath.stringByAppendingString(dbName)

        let fileManager:NSFileManager = NSFileManager.defaultManager()
        dbWrapper = Sqlite3Wrapper(fileName: dbName)
        if !fileManager.fileExistsAtPath(dbPath) {
            if dbWrapper.openDatabase() == false {
                NSLog("Database not opened")
                let sql:NSString = "CREATE TABLE IF NOT EXISTS CONTACTS (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT, ADDRESS TEXT, PHONE TEXT)"
                if dbWrapper.executeStatement(sql) {
                    NSLog("Table Created")
                }
                dbWrapper.closeDatabase()
            } else {
                NSLog("Database opened")
            }
        } else {
            NSLog("Database exists")
        }
    }

    public func open() -> Bool {
        return dbWrapper.openDatabase()
    }

    public func test(dbName:NSString) {
        let docDirPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString
        let dbPath:NSString = docDirPath.stringByAppendingString(dbName)

        let fileManager:NSFileManager = NSFileManager.defaultManager()

        if !fileManager.fileExistsAtPath(dbPath) {
            if Sqlite3Wrapper(fileName: dbPath) == false {
                NSLog("Database not opened")
                let sql:NSString = "CREATE TABLE IF NOT EXISTS CONTACTS (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT, ADDRESS TEXT, PHONE TEXT)"
                if dbWrapper.executeStatement(sql) {
                    NSLog("Table Created")
                }
                dbWrapper.closeDatabase()
            } else {
                NSLog("Database opened")
            }
        } else {
            NSLog("Database exists")
        }
    }
}

public func logMessage(message: NSString ) {
    NSLog("Message is printed")
}

public func createDatabase(dbName: NSString ) {
    Data(dbName: dbName)
}