iphone - simple - Importe el error sqlite3.h: incluye un encabezado no modular dentro del módulo del marco
swift 4 sqlite insert into (2)
Por lo que sé, no puede importar directamente archivos Objective-C a Swift en un marco. Pero podrías hacerlo en otras clases de Objective-C en el mismo marco. Entonces, si escribe una clase Objective-C en su marco, podrá incluir el archivo de encabezado directamente en su clase y usarlo.
Con el mismo propósito, terminé escribiendo una clase contenedora para sqlite.h
en Objective-C y luego sqlite.h
a eso en mi código Swift. El encabezado de la clase contenedora que escriba debe hacerse público y agregarse a su encabezado paraguas.
Escribí algo como esto:
#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
Cada una de estas funciones ajusta los métodos sqlite3. Estos podrían ser llamados desde sus clases Swift en el mismo marco.
Estoy creando un marco de back-end personalizado para mi aplicación que encapsula toda mi lógica relacionada con la base de datos, por lo tanto, cuando vamos a utilizar cualquier operación de base de datos, solo necesitamos llamar a esa función de framework.
Ahora, para las operaciones de la base de datos, necesito #import <sqlite3.h>
en el archivo llamado Data.swift, donde están todas mis funciones de base de datos. Pero este es un archivo rápido, así que ¿cómo puedo importar sqlite ...?
Cuando uso bridging-header.h, recibo un error
error: using bridging headers with framework targets is unsupported
bridging-header.h tiene #import <sqlite3.h>
en su interior y establece la configuración de Bridging Header variable.
Si agrego declaración de importación en el encabezado de Umbrella que me da el error
include of non-modular header inside framework module
Busqué en Google pero no pude encontrar la respuesta adecuada. También miré https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html#//apple_ref/doc/uid/TP40014216-CH10-XID_82 y lo seguí correctamente, pero creo Aún extraño algo.
Por favor sugiérame algo.
He tomado un archivo Object C y lo he personalizado un poco.
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
Estoy usando este archivo envoltorio y he creado un archivo rápido.
Logger.swift
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)
}
Las últimas 2 funciones createDatabase
y logMessage
son solo temporales para probar si puedo acceder a estas funciones directamente o no.
También he creado un "objetivo agregado" para el marco universal para dispositivos y simuladores. Pero cuando uso este marco universal, no puedo import Logger
y recibe el error "No such module ''Logger''". Pero cuando empaque el marco para el dispositivo y trato de agregar el mismo marco, puedo hacer la importación.
Finalmente, el problema es que una vez que import Logger
, no puedo acceder a ninguna función o clase de Data
del marco. Solo puedo acceder a Sqlite3Wrapper
que está escrito en el Objetivo C. Quiero usar esa clase de datos o funciones públicas.
Por favor, avíseme si cree que estoy haciendo algo mal.