Swift:生成对象的超类方法的替代品

时间:2017-04-20 18:07:37

标签: objective-c swift

我有以下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"
        }
    )
}

2 个答案:

答案 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)
    }
}

以下是一些值得注意的要点:

  1. Book是一个结构。如此广泛的书籍描述并不需要支持身份的概念。即,你的书名为" Harry Potter",by#34; J.K。罗林"描述"一些描述"可以被认为与具有相同值的我的书相同。目前还没有必要区分你的书的身份和我的身份。

  2. Book有一个隐式的成员初始值设定项init(title:author:description:),它只是将其字段初始化为给定的参数。

  3. 进行扩展,将所有字典相关任务划分为一个单元。

  4. 创建了一个可用的初始化程序init?(fromDictArray:),它根据给定的dict(可能是从您的JSON创建)返回一本新书。该初始化程序具有容错能力。如果提供的字典无效,则初始化程序将只返回nil,而不会导致程序崩溃。

  5. 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
}