Untitled
unknown
swift
3 years ago
8.8 kB
11
Indexable
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
}
}
}Editor is loading...