【问题标题】:Swift: "Mapper is not a type", using custom mapping class for arrays in swift and Objective CSwift:“映射器不是类型”,在 swift 和 Objective C 中为数组使用自定义映射类
【发布时间】:2016-12-14 22:52:51
【问题描述】:

我有 2 个客观的 C 类:

  • 1 类 scanDatabase(扫描数据库并将其放入可变数组)
  • 2 类映射器(是数据库扫描“模型”的映射类)

在目标 C 中,这成功地扫描了数据库并将其放入一个可变数组中。使用映射类,我可以访问单个元素组(AlbumTitles),如下所示:

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

一切正常,我可以从我的数组中返回单个元素,即如上所述,我只返回专辑标题。

然后我需要在 Swift 中使用该数组。我在我的 Swift 类中调用了目标 C,它再次运行良好并创建了数组。这是通过以下方式完成的:

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

scanTable.scanTableDo();

但是当我尝试检索像专辑标题这样的特定项目集时,就像我在上面的目标 C for 循环中所做的那样,我收到错误“scanMapper 不是类型”(scanMapper 是我的目标 C 映射器类的快速实例:

我尝试了两种不同的方法,但都有相同的错误:

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


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

我可以使用一个客观的 C 类作为模型/映射器,但不确定是否需要在 Swift 中重新创建它。

我将包含映射器和 scanTable .h 和 .m 代码以备不时之需,以及桥接头:

映射器.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

映射器.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

//编辑添加桥接头//

MySampleApp-Bridging-Header.h:

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

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

感谢您的帮助

【问题讨论】:

    标签: objective-c arrays swift types


    【解决方案1】:

    问题就像错误解释的那样,您试图将数组中的项目转换为scanMapper,这是一个包含Mapper 实例的变量,而不是Mapper 类型本身。假设 scanTable.scanResult 是一个映射器的 NSArray,试试这个:

    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)")
    }
    

    【讨论】:

    • 感谢您的回复帕特里克。 “Mapper”是用Objective C编写的,所以不确定我如何以你提到的方式引用它?我的问题是我必须快速重写映射类,并有一个用于保存(Obj - C)和一个用于检索(Swift)。我试过你说的方法,我得到错误“NSArray不符合协议序列类型”。
    • @NicholasMuir 你创建了一个Objective-C桥接头了吗?如果没有,请查看本指南:learnswiftonline.com/getting-started/… 我将更新答案以使用 NSArray。
    • 是的,我有。我将使用桥接头编辑我的问题。目标 C scanTableDo() 函数正在被 swift 调用并且运行正常。我在桥接头中也有 Mapper 类。
    • @NicholasMuir 已更新。如果我的示例不适合您,请告诉我。
    • @NicholasMuir 已修复。
    猜你喜欢
    • 1970-01-01
    • 2019-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-15
    • 2016-03-30
    相关资源
    最近更新 更多