Untitled
unknown
swift
2 years ago
8.8 kB
4
Indexable
Never
import UIKit struct VKNews { private var items: [VKNew] private var profiles: [VKUser] private var groups: [VKGroup] let nextFrom: String init?(){ self.items = [] self.profiles = [] self.groups = [] self.nextFrom = "" } func news() -> [VKNew]{ var news: [VKNew] = [] self.items.forEach{ new in switch new.sourceType{ case .profile: let profile = self.profiles.first{ $0.id == new.sourceID } let tempName = profile?.name ?? "" let tempURL = profile?.photoURL guard var tempNew = VKNew(new: new, sourceName: tempName, photoUrl: tempURL) else {return} tempNew.buildCellsArray() news.append(tempNew) case .group: let group = self.groups.first{ $0.id == new.sourceID } let tempName = group?.name ?? "" let tempURL = group?.photoURL guard var tempNew = VKNew(new: new, sourceName: tempName, photoUrl: tempURL) else {return} tempNew.buildCellsArray() news.append(tempNew) } } return news } } struct VKNew { let text: String var shortText: String? var isShortText: Bool? var photos: [VKNewsPhoto] = [] var docs: [VKNewsDoc] = [] private var cellsCounter: [(VKBlocksType,Int)] = [] let date: Double let stringDate: String let sourceID: Int let sourceType: SourceType var sourceName = "" var photoUrl: URL? = nil let likesCount: Int let isLiked: Bool let repostsCount: Int let isReposted: Bool let viewsCount: Int init?(new: VKNew, sourceName: String, photoUrl: URL?){ self = new self.sourceName = sourceName self.photoUrl = photoUrl if self.text.count > 200 { shortText = String(text.prefix(200)) + "..." isShortText = true } } mutating func buildCellsArray(){ if !text.isEmpty{ cellsCounter.append((.text,0)) } if !photos.isEmpty{ cellsCounter.append((.photos,0)) } for i in (0..<docs.count){ cellsCounter.append((.docs,i)) } } func returnCellsCounter() -> [(VKBlocksType,Int)] { return cellsCounter } } enum VKBlocksType{ case text case photos case docs } struct VKNewsPhoto { let sizes: [VKPhotoSize] var aspectRatio: Double? { guard let size = self.sizes.first, let height = size.height, let width = size.width else { return nil } return Double(height) / Double(width) } } struct VKNewsDoc { let title: String let size: Int let url: URL? } extension VKNews: Decodable { enum CodingKeys: String, CodingKey{ case items case profiles case groups case nextFrom = "next_from" } } extension VKNew: Decodable{ enum NewCodingKeys: String, CodingKey{ case text case attachments case date case sourceID = "source_id" case likes case reposts case views } enum LikesCodingKeys: String, CodingKey{ case count case userLikes = "user_likes" } enum RepostsCodingKeys: String, CodingKey{ case count case userReposted = "user_reposted" } enum ViewsCodingKeys: String, CodingKey{ case count } enum AttachmentsCodingKeys: String, CodingKey{ case type case photo case doc } enum DocsCodingKeys: String, CodingKey{ case title case size case url } enum PhotosCodingKeys: String, CodingKey{ case sizes } enum SizesCodingKeys: String, CodingKey{ case type case url case height case width } enum SourceType: String{ case profile = "profile" case group = "group" init?(_ param: String){ switch param{ case "profile": self = .profile default: self = .group } } } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: NewCodingKeys.self) self.text = try container.decode(String.self, forKey: .text) if container.contains(.attachments) { var attachmentsContainer = try container.nestedUnkeyedContainer(forKey: .attachments) while(!attachmentsContainer.isAtEnd){ let attachmentContainer = try attachmentsContainer.nestedContainer(keyedBy: AttachmentsCodingKeys.self) let type = try attachmentContainer.decode(String.self, forKey: .type) switch type{ case "photo": let photoContainer = try attachmentContainer.nestedContainer(keyedBy: PhotosCodingKeys.self, forKey: .photo) var sizesContainer = try photoContainer.nestedUnkeyedContainer(forKey: .sizes) var tempSizes: [VKPhotoSize] = [] while(!sizesContainer.isAtEnd){ let sizeContainer = try sizesContainer.nestedContainer(keyedBy: SizesCodingKeys.self) let tempUrlString = try sizeContainer.decode( String.self, forKey: .url) let url = URL(string: tempUrlString) let type = try sizeContainer.decode(String.self, forKey: .type) let tempHeight, tempWidth: Int? if sizeContainer.contains(.height) { tempHeight = try sizeContainer.decode( Int.self, forKey: .height) tempWidth = try sizeContainer.decode( Int.self, forKey: .width) } else { tempHeight = nil tempWidth = nil } tempSizes.append( VKPhotoSize( url: url, sizeType: type, height: tempHeight, width: tempWidth)) } self.photos.append(VKNewsPhoto(sizes: tempSizes)) case "doc": let docContainer = try attachmentContainer.nestedContainer(keyedBy: DocsCodingKeys.self, forKey: .doc) let title = try docContainer.decode(String.self, forKey: .title) let size = try docContainer.decode(Int.self, forKey: .size) let tempUrl = try docContainer.decode(String.self, forKey: .url) let url = URL(string: tempUrl) let doc = VKNewsDoc(title: title, size: size, url: url) self.docs.append(doc) default: continue } } } self.date = try container.decode(Double.self, forKey: .date) self.stringDate = self.date.date() let tempSourceID = try container.decode(Int.self, forKey: .sourceID) self.sourceID = abs(tempSourceID) self.sourceType = (tempSourceID > 0) ? SourceType.profile : SourceType.group let likesContainer = try container.nestedContainer(keyedBy: LikesCodingKeys.self, forKey: .likes) self.likesCount = try likesContainer.decode(Int.self, forKey: .count) let tempIsLiked = try likesContainer.decode(Int.self, forKey: .userLikes) self.isLiked = Bool(truncating: NSNumber(value: tempIsLiked)) let repostsContainer = try container.nestedContainer(keyedBy: RepostsCodingKeys.self, forKey: .reposts) self.repostsCount = try repostsContainer.decode(Int.self, forKey: .count) let tempIsReposted = try repostsContainer.decode(Int.self, forKey: .userReposted) self.isReposted = Bool(truncating: NSNumber(value: tempIsReposted)) if container.contains(.views){ let viewsContainer = try container.nestedContainer(keyedBy: ViewsCodingKeys.self, forKey: .views) self.viewsCount = try viewsContainer.decode(Int.self, forKey: .count) } else { self.viewsCount = 0 } } }