Передача json из класса в класс

swift

#1

Всем привет! Ребята сильно не пинайте может повторяюсь. Нужен совет Имею класс который получает json данные. Эти данные передаю в др. класс чтобы отобразить во вью. Обмен через структуру. Сложность в том, что данные получаю, а вот во вью не передаются.

struct DetailDataFilm: Codable {
var data:DetailInfoFilm 
}

struct DetailInfoFilm: Codable {
var id: Int? = nil
var name: String = "" 
var premiere: String = ""
var duration: String = ""
var annotationFull: String = ""
var ageLimit: Int? = nil
var genre: String = ""
}

Класс делает запрос

import Foundation   
 class GetJsonDetailFilmInfo:NSObject {
       
 var anonceMenuFilms: SheduleFilm?
 var movieInfoTextView = DetailInfoFilm()

func getInfoMovie () {
    let urlString = ""http://х.х.х.х:х/api/v2/
    let url = URL(string: urlString)
    URLSession.shared.dataTask(with: url!) { (data, response, error) in
        do {
            let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String: Any]
            guard  let dataToken = json["data"] as? String else {return}
            let urlString = "http://х.х.х.х:х/api/v2/films/?id=4498
            let url = URL(string: urlString)
            URLSession.shared.dataTask(with: url!) { (data, response, error) in
                if error != nil {
                    print(error as Any)
                    return
                }
                do {

                    let decoder = JSONDecoder()

                    decoder.keyDecodingStrategy = .convertFromSnakeCase

                    let jsonData = try decoder.decode(DetailDataFilm.self, from: data!)

                    var filmShedule = DetailInfoFilm()

                    DispatchQueue.main.async(execute: {() -> Void in

                       self.movieInfoTextView.annotationFull = jsonData.data.annotationFull

                    print("(self.movieInfoTextView.annotationFull)")
                })
                }
                catch {
                    print(error)
                }
                }.resume()
        } catch {
            print(error)
        }
        }.resume()
}
}

Класс принимающий и отображающий

import UIKit

class DetailsFilmsViewController: UIViewController {
var getInfoFilm = DetailInfoFilm()
var anonceMenuFilms: SheduleFilm?
var getDeteilInfo = GetJsonDetailFilmInfo()

@IBOutlet weak var movieInfoTextView: UITextView! {
    didSet {
        movieInfoTextView.text =  movieInfoTextView.annotationFull
    }
}


override func viewDidLoad() {
 super.viewDidLoad()
}

#2

У вас какая-то каша в коде. Судя по тому что вы инициализируете свой класс во ViewController’e, у вас совпадают имена movieInfoTextView. В классе это структура, в VC это TextView. Я бы предположил что у вас вообще должен catch срабатывать.

  1. Сделайте нормальные имена переменным, элементам.
  2. После того как вы сделали инициализацию своего класса, элементы VC еще не созданы.
  3. Добавьте параметр в ваш метод, передавайте туда элемент для отображения данных.
  4. Вызывайте ваш метод во viewDidLoad.

P.S. вот это вообще не используется var filmShedule = DetailInfoFilm()


#3

Все это 3 разных файла. Что касаемо var filmShedule = DetailInfoFilm() используется я просто убрал все что с этим связано. Остальное поправим)


#4

Уля-ля все ОК, Спасибо!

  **RexHunt**

#5

Подскажите как здесь передать данные. Пробую через структуру
var arraySheduleFilms: [SheduleFilm] = []. Метод отрабатывает нормально, а в структуру ничего не приходит. Метод конечно кривой, но рабочий переделаю как разберусь с передачами параметров.

import UIKit

class DataManager {

var arraySheduleFilms: [SheduleFilm] = []

func filmsMenu (dates: String)  {
   
    let token = GetToken.init().getToken()
    let urlString = "http://хх.хх.хх.хх/api/v2/getToken/?type=base&ais="+token
    let url = URL(string: urlString)
    
    URLSession.shared.dataTask(with: url!) { (data, response, error) in
        
        do {
            let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String: AnyObject]
            
            guard  let dataToken = json["data"] as? String else {return}
            
            let urlString = "http://хх.хх.хх.хх/api/v2/schedule/?date="+dates+"&token="+dataToken
            print(urlString)
            
           self.arraySheduleFilms.removeAll()
            
            let url = URL(string: urlString)
            URLSession.shared.dataTask(with: url!) { (data, response, error) in
                if error != nil {
                    print(error as Any)
                    return
                }
                print(data!)
                do {
                    let decoder = JSONDecoder()
                    let jsonData = try decoder.decode(Datas.self, from: data!)
                   
                    var _arraySheduleFilms: [SheduleFilm] = []
                    var filmShedule = SheduleFilm()
                    let anonce = AnonceMenu()
         
                    jsonData.data.forEach {
                        
                        if $0.film.contains(" ATMOS 3D") {
                            filmShedule.film = $0.film.components(separatedBy: " ATMOS 3D").joined(separator: "")
                        }
                        else if $0.film.contains(" 3D") {
                            filmShedule.film = $0.film.components(separatedBy: " 3D").joined(separator: "")
                        }
                        else if $0.film.contains(" ATMOS 2D") {
                            filmShedule.film = $0.film.components(separatedBy: " ATMOS 2D").joined(separator: "")
                        }
                        else if $0.film.contains(" ATMOS") {
                            filmShedule.film = $0.film.components(separatedBy: " ATMOS").joined(separator: "")
                        }
                        else {
                            filmShedule.film = $0.film
                        }
                        
                        filmShedule.datetime = $0.datetime
                        filmShedule.bigPoster = $0.bigPoster
                        anonce.nameFilm = $0.film
                        filmShedule.trailer = $0.trailer
                        filmShedule.filmId = $0.filmId

                        _arraySheduleFilms.append(filmShedule)
                    }
                    
                    let dictionarySheduleFilm = Dictionary(grouping: _arraySheduleFilms, by: { $0.film } )
                    
                    for (key, value) in dictionarySheduleFilm {

                        anonce.nameFilm = key
                        filmShedule.film = key
                        // filmShedule.trailer = key
                        
                        for valueBigPoster in value {
                            anonce.imag = valueBigPoster.bigPoster
                            filmShedule.bigPoster = valueBigPoster.bigPoster
                            filmShedule.trailer = valueBigPoster.trailer
                            filmShedule.filmId = valueBigPoster.filmId
                        }
                        
                        self.arraySheduleFilms.append(filmShedule)
                    }
 //                        DispatchQueue.main.async {
//                            collection.reloadData()
//                        }
                     } catch  {
                    print (error)
                }
                }.resume()
        } catch  {
            print (error)
        }
        
        }.resume()
}

}


#6

Покажите ваши структуры и json ответ.


#7

эт показать не проблема

Покажите ваши структуры и json ответ.

Когда все в контроллере, то работает. Вынес в отдельный класс. не работает (


#8

Структура

   import Foundation
struct Datas:Codable {
var data:[SheduleFilm]
}

struct SheduleFilm:Codable {
var filmId: Int?
var film: String = ""
var datetime: String = ""
var bigPoster: String?
var trailer: String?

}

JSON

 {
 code: 0,
 message: "OK",
 data: [
 {
 datetime: "2018-11-08 12:40:00",
 filmId: 4578,
 film: "Богемская рапсодия",
 bigPoster: "http://XXXXXX/img/movie/9364_big.jpg?1537967384",
 trailer: "https://XXXXXX/preview/BohemianRhapsody_TLR-7_S_RU-XX_RU-18_51_2K_TCF_20180513_EKN_IOP_OV.mp4",
}
 ]

#9

Структуры верные. Преобразование ответа в модель верная. Посмотрите что у вас в каждом цикле происходит. Добавляются ли данные в массивы. Можете просто коунт смотреть.


#10

Содержимое массива

self.arraySheduleFilms.append(filmShedule)
     for i in self.arraySheduleFilms {
 print(i)
 }
SheduleFilm(filmId: Optional(4555), film: "Смолфут", datetime: "2018-11-09 00:15:00", bigPoster: Optional("http://nas.dcp24.ru/img/movie/9324_big.jpg?1537860730"), trailer: Optional("https://nas.dcp24.ru/preview/200597_Smallfoot_TLR-F2ALT-2D_F_RU-XX_RU-6_51_2K_SPE_20171118_DTU_IOP_OV.mp4"))

#11

Т.е. в массив что-то заносится. Так в чем тогда проблема?


#12

когда я обращаюсь к

то там пусто. Либо я что-то ни так делаю
Содержимое массива которое было выше это print из метода, там массив заполняется.


#13

Попробуйте вынести self.arraySheduleFilms.removeAll() в самое начало метода, до запроса.


#14

и это не помогает ((((


#15

А покажите как вы работаете с этим классом.


#16

Для проверки я сделал в этом же классе

class DataManager     
func testElemens() {
  for i in arraySheduleFilms {
    print("TEST TEST TEST \(i)")
}

  filmMenu(dates: self.currentData) {
  тело метода
 ....
 }
}

вызываю в классе

 class CollectionViewControllerMenu: UICollectionViewController {
  @IBOutlet var dataProvider: DataProvider!

var dataManagerJson = DataManager()
var currentData = CurrentDate().date()

override func viewDidLoad() {
    super.viewDidLoad()
    
    dataManagerJson.filmsMenu(dates: self.currentData)
   dataManagerJson.testElemens()


}

}


#17

Попробуйте добавить closure

func filmsMenu (dates: String, closure: [SheduleFilm]() -> ()) {
    ...
         self.arraySheduleFilms.append(filmShedule)
    }
    closure(self.arraySheduleFilms)
}

И уже у себя в VC работайте так

dataManagerJson.filmsMenu(dates: self.currentData) { arraySheduleFilms in
    // работайте уже с полученными данными и таблицей
    for i in arraySheduleFilms {
        print(i)
    }
}

#18

Исправляю на это

func filmsMenu (dates: String, closure: [SheduleFilm]) -> ()

а тут

closure(self.arraySheduleFilms)

выдает это

Cannot call value of non-function type '[SheduleFilm]'

#19

Пардон, мой косяк, опечатался
Должно быть так

func filmsMenu (dates: String, closure: ([SheduleFilm]) -> ()) {


#20

Ну и ну заработало +1

RexHunt :+1::+1::+1: Большое спасибо !!! :grinning::grinning::grinning:

только пришлось дописать

func filmsMenu  (dates: String, closure: **@escaping** ([SheduleFilm]) -> ())

Теперь предстоит все эт передать в CollectionView
который находится в отдельно классе )))). Но эт уже другая история ))).
Может осилю сам )))