2016-08-09 60 views
0

Ich habe eine 2 objektiven C-Klassen:Swift: "Mapper ist kein Typ", benutzerdefinierte Mapping-Klasse für Arrays in schnellen und Objective C mit

  • Klasse 1 scanDatabase (Scans eine Datenbank und legt in ein, dass änderbare Array)
  • Klasse 2 Mapper (Ist eine Mapping-Klasse für das Datenbank-Scan "Modell")

in Objective C dies erfolgreich die Datenbank durchsucht und in ein änderbares Array setzt. Mit Hilfe der Mapping-Klasse kann ich auf einzelne Gruppen von Elementen (AlbumTitles) wie folgt:

for (Mapper *mapper in scanResult) { 
    NSLog(@"%@", mapper.AlbumTitle); 
} 

Alles funktioniert, wie es sollte, und ich einzelne Elemente aus meinem Array d.h zurückkehren kann, wie oben ich nur Albumtitel Rückkehr bin.

Ich muss dann dieses Array in Swift verwenden. Ich nenne das Ziel C in meiner Swift-Klasse und wieder läuft es gut und erstellt das Array. Dies geschieht mit:

let scanTable = ScanTable(); 
let scanMapper = Mapper(); 

scanTable.scanTableDo(); 

aber wenn ich versuche, eine bestimmte Menge von Elementen wie Albumtitel abzurufen, wie ich in dem Ziel C for-Schleife hat oben ich den Fehler „scanMapper ist kein Typ“ (scanMapper ist meine rasche Instanz der Ziel C-Mapper-Klasse:

habe ich versucht, zwei verschiedene Arten und beide haben die gleichen Fehler:

for mapper: scanMapper in scanTable.scanResult { 
     print("\(mapper.AlbumTitle)") 
    } 


for object in scanTable.scanResult as! [scanMapper] { 
    print("\(mapper.AlbumTitle)") 
} 

Kann ich eine objektive C-Klasse als Modell/Mapper verwenden und nicht sicher, ob ich müsste es in Swift neu erstellen.

Ich werde die Mapper und Suchtabelle .h und .m-Code enthalten für den Fall, es benötigt wird, sowie die Überbrückung Header:

Mapper.h:

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

@interface Mapper : AWSDynamoDBObjectModel <AWSDynamoDBModeling> 

@property (nonatomic, strong) NSNumber *SongID; 
@property (nonatomic, strong) NSString *Artist; 
@property (nonatomic, strong) NSString *SongURL; 
@property (nonatomic, strong) NSString *Location; 
@property (nonatomic, strong) NSNumber *UserRatings; 
@property (nonatomic, strong) NSNumber *AVGUserRating; 
@property (nonatomic, strong) NSString *Category; 
@property (nonatomic, strong) NSString *PictureURL; 
@property (nonatomic, strong) NSNumber *SongDuration; 
@property (nonatomic, strong) NSString *SongTitle; 
@property (nonatomic, strong) NSNumber *AVGMusicianRating; 
@property (nonatomic, strong) NSString *AlbumTitle; 

@end 

Mapper.m

#import <AWSDynamoDB/AWSDynamoDB.h> 
#import "Mapper.h" 

@implementation Mapper 

+ (NSString *)dynamoDBTableName { 
    return @"Songs"; 
} 

+ (NSString *)hashKeyAttribute { 
    return @"SongID"; 
} 

@end 

ScanTable.h:

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

@interface ScanTable : NSObject 

- (void) scanTableDo; 
@property (nonatomic, strong) NSMutableArray *scanResult; 

@end 

ScanTable.m

#import "ScanTable.h" 
#import "Mapper.h" 

@implementation ScanTable 

- (void) scanTableDo { 

    AWSDynamoDBObjectMapper *dynamoDBObjectMapper = [AWSDynamoDBObjectMapper defaultDynamoDBObjectMapper]; 
    AWSDynamoDBScanExpression *scanExpression = [AWSDynamoDBScanExpression new]; 
    scanExpression.limit = @10; 


    [[dynamoDBObjectMapper scan:[Mapper class] 
        expression:scanExpression] 
    continueWithBlock:^id(AWSTask *task) { 
     if (task.error) { 
      NSLog(@"The request failed. Error: [%@]", task.error); 
     } 
     if (task.exception) { 
      NSLog(@"The request failed. Exception: [%@]", task.exception); 
     } 
     if (task.result) { 
      AWSDynamoDBPaginatedOutput *paginatedOutput = task.result; 
      NSMutableArray *scanResult = [[NSMutableArray alloc] initWithArray:paginatedOutput.items]; //// ADDED ///// 

      for (Mapper *mapper in scanResult) { 
       NSLog(@"%@", mapper.AlbumTitle); 
      } 
     } 
     return nil; 
    }];    
} 

@end 

// EDITED ADDED HEADER BRIDGING //

MySampleApp-Bridging-header.h:

// 
// MySampleApp-Bridging-Header.h 
// MySampleApp 

#import "ScanTable.h" 
#import "Mapper.h" 
#import "Hello World.h" 

Danke für Ihre Hilfe

Antwort

1

Das Problem ist, wie der Fehler erklärt , Sie versuchen, die Elemente in Ihrem Array zu scanMapper zu konvertieren, das eine Variable ist, die eine Instanz von , nicht den -Typ selbst enthält. Angenommen, dass scanTable.scanResult ist ein NSArray Mapper, versuchen Sie dies stattdessen:

guard let scanResult = scanTable.scanResult as? [Mapper] else { 

    print("scanResult was not an array of mappers!") 
    return 
} 

for mapper: Mapper in scanResult { 

    print("\(mapper.AlbumTitle)") 
} 
+0

Vielen Dank für Ihre Antwort Patrick. "Mapper" ist in Objective C geschrieben, also nicht sicher, wie ich es in der von Ihnen erwähnten Weise referenzieren kann?Diese Art von Feeds in meine Frage muss ich die Mapping-Klasse in Swift neu schreiben und eine zum Speichern (Obj - C) und eine zum Abrufen (Swift) haben. Ich habe versucht, wie Sie sagten, und ich bekomme den Fehler "NSArray entspricht nicht Protokoll Sequenztyp". –

+1

@NicholasMuir Hast du schon einen Objective-C Bridging Header erstellt? Sehen Sie sich diese Anleitung an, wenn nicht: http://www.learnswiftonline.com/getting-started/adding-swift-bridging-header/ Ich werde die Antwort auf die Arbeit mit NSArray aktualisieren. –

+0

Ja, habe ich. Ich werde meine Frage mit dem Bridging-Header bearbeiten. Die objektive C-Funktion scanTableDo() wird von swift aufgerufen und läuft ordnungsgemäß. Ich habe auch die Mapper-Klasse im Bridging-Header. –