我有以下Objective-C代码我正在尝试转换为swift:
-(id)initWithBook:(NSString*)bookTitle author:(NSString*)author description:(NSString*)description{
self = [super init];
if (self) {
self.bookTitle = [bookTitle copy];
self.author = [author copy];
self.description = [uri description];
}
return self;
}
+(NSArray*)listOfBooks:(NSArray*)jsonWithBooks{
NSMutableArray *elements = [NSMutableArray new];
for (NSDictionary *dictElment in jsonRespnse){
Books *booksData = [[Books alloc] initWithBook:[dictElment objectForKey:@"bookTitle"]
title:[dictElment objectForKey:@"author"]
description:[dictElment objectForKey:@"description"]];
[elements addObject:booksData];
}
return [NSArray arrayWithArray:elements];
}
在我的Objective-C代码中,我正在调用超类“+(NSArray *)listOfBooks:(NSArray *)jsonWithBooks”来生成对象的NSArray。但我还没有找到一个关于Swift的等价物。你们中的任何人都知道做这样的事情的最佳选择是什么?
我正在尝试使用@Alexander示例,但我的项目在以下行崩溃:
let inventoryBooks = Book.books(fromDictArray: json .object(forKey: "books") as! [[String : String]] )
我检查了这个类型:
json .object(forKey: "books")
如下:
let arrayOfBooks = json .object(forKey: "books")
if arrayOfBooks is NSArray {
print("nsarray")
}
if arrayOfBooks is [[String:String]] {
print("string:string")
}
if arrayOfBooks is NSDictionary {
print("NSDic")
}
正在打印nsarray
我的问题。我做错了什么或者我需要更改此功能的签名:
static func books(fromDictArray array: [[String: String]]) -> [Book?] {
return array.map(Book.init)
}
这个json响应样本:
{
books = (
{
caption = "";
"display_sizes" =(
{
name = thumb;
uri = "https://someUrl.com/img.jpg";
}
);
id = 123;
"max_dimensions" = {
height = 4912;
width = 7360;
};
title = "Learning Swift";
author = "Some guy"
}
{
caption = "";
"display_sizes" =(
{
name = thumb;
uri = "https://someUrl.com/img.jpg";
}
);
id = 123;
"max_dimensions" = {
height = 4912;
width = 7360;
};
title = "Swift";
author = "me meme"
}
)
}
答案 0 :(得分:3)
以下是我在惯用的Swift中编写此代码的方法:
struct Book {
let title: String
let author: String
let description: String
/* an implicit member wise initializer is generated,
which would otherwise look something like this:
init(title: String, author: String, description: String) {
self.title = title
self.author = author
self.description = description
} */
}
// Initialization from Dictionaries
extension Book {
init?(fromDict dict: [String: Any]) {
guard
let title = dict["bookTitle"] as? String,
let author = dict["author"] as? String,
let description = dict["description"] as? String
else { return nil }
self.init(
title: title,
author: author,
description: description
)
}
static func books(fromDictArray array: [[String: Any]]) -> [Book?] {
return array.map(Book.init)
}
}
以下是一些值得注意的要点:
Book
是一个结构。如此广泛的书籍描述并不需要支持身份的概念。即,你的书名为" Harry Potter",by#34; J.K。罗林"描述"一些描述"可以被认为与具有相同值的我的书相同。目前还没有必要区分你的书的身份和我的身份。
Book
有一个隐式的成员初始值设定项init(title:author:description:)
,它只是将其字段初始化为给定的参数。
进行扩展,将所有字典相关任务划分为一个单元。
创建了一个可用的初始化程序init?(fromDictArray:)
,它根据给定的dict(可能是从您的JSON创建)返回一本新书。该初始化程序具有容错能力。如果提供的字典无效,则初始化程序将只返回nil
,而不会导致程序崩溃。
在static
结构Book
上进行books(fromDictArray:)
方法,该结构将创建一系列可选图书([Book?]
,即Array<Optional<Book>>
然后,这个方法的消费者的工作就是处理nil
值,这些值是由无效的词组产生的,因为他们喜欢。
他们可以忽略nil
本书:
let books = Book.books(fromDictArray: myDictArray).flatMap{$0}
如果找到nil
本书,它们可能会崩溃:
let books = Book.books(fromDictArray: myDictArray) as! [Book]
或者他们可以用一些独特的方式处理零案例:
let books = Book.books(fromDictArray: myDictArray).map{ book in
if book == nil {
print("A nil book was found")
}
}
答案 1 :(得分:0)
正如已经被 Dan 所暗示的那样,Swift的等价物将是 class func
:
class func listOfBooks(jsonWithBooks: [NSDictionary]) -> [Book] {
var books = [Book]()
for json in jsonWithBooks {
let book = Book(
book: json["bookTitle"]!,
author: json["author"]!,
description: json["description"]!
)
books.append(book)
}
return books
}