0

I want to save kode_pelaksanaan in user default and retrieve it in second view controller using SwiftyJSON and Alamofire. this my code

class ListSelfLearningViewController: UIViewController{

     @IBOutlet weak var collectionView: UICollectionView!

     var listSelfLearning: [ListSelfLearningModel] = [] 

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

extension ListSelfLearningViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return self.listSelfLearning.count
}

func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 1
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ListSelfLearningCollectionViewCell", for: indexPath) as! ListSelfLearningCollectionViewCell
    //cell.profileIv.image = listSelfLearning[indexPath.row].listImage
    cell.profileIv.sd_setImage(with: URL(string: listSelfLearning[indexPath.row].listImage))
    cell.title.text = listSelfLearning[indexPath.row].labelName
    return cell
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize.init(width: UIScreen.main.bounds.width - 20, height: 250)
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    let storyboard: UIStoryboard = UIStoryboard(name: "Home", bundle: nil)
    let vc = storyboard.instantiateViewController(withIdentifier: "ListActivityViewController") as! ListActivityViewController
    navigationController?.pushViewController(vc, animated: true)
}

func fetchData(){
    DispatchQueue.main.async {
        let url = URLs.listImage
        guard let user = helper.getApiUser() else{ return }

        guard let token = helper.getApiToken() else{ return }

        let parameter  = [
            "request": "{\"requestMethod\":\"list_selflearning\",\"user\":\"\(user)\"}"

        ]

        let headers: HTTPHeaders = [
            "Content-Type" : "application/x-www-form-urlencoded",
            "Authorization" : "Bearer \(token)"
        ]

        Alamofire.request(url, method: .post, parameters: parameter, headers: headers).responseJSON(completionHandler: { (response) in
            switch response.result{
            case .success(let value):
                let json = JSON(value)
                if let data = json["responseData"].array{
                    for item in data{
                        let images = item["image_detail"]["path_image"].string
                        let namaPelaksana = item["nama_pelaksanaan"].string

                        if let kode_pelaksanaan = item["kode_pelaksanaan"].string{
                            helper.saveKodePelaksanaan(kode_pelaksanaan: kode_pelaksanaan)
                            print("nilai kode pelaksanaan: \(kode_pelaksanaan)")
                        }

                        let listData = ListSelfLearningModel(listImage: images!, labelName: namaPelaksana!)
                        self.listSelfLearning.append(listData)

                    }
                }

                self.collectionView.reloadData()

            case .failure(let error):
                print(error)
            }
        })
    }
}
}

this output when print user default:

nilai kode pelaksanaan: ELR2018120005
nilai kode pelaksanaan: ELR2018120004
nilai kode pelaksanaan: ELR2018120003
nilai kode pelaksanaan: ELR2018120001
nilai kode pelaksanaan: ELR2018050004

but when I retrieve in second class for parameter but I didn't get output like I save in Userdefault.

this my code in second view controller:

import UIKit
import SwiftyJSON
import Alamofire
import SDWebImage

class ListActivityViewController: UIViewController {

@IBOutlet weak var tableView: UITableView!
var listActivity: [ListActivity] = []

override func viewDidLoad() {
    super.viewDidLoad()
    tableView.delegate = self
    tableView.dataSource = self
    // Do any additional setup after loading the view.
    let nibCell = UINib(nibName: "ListActivityTableViewCell", bundle: nil)
    tableView.register(nibCell, forCellReuseIdentifier: "ListActivityTableViewCell")
    fetchData()
}

}

    extension ListActivityViewController: UITableViewDataSource, UITableViewDelegate{
func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return listActivity.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "ListActivityTableViewCell", for: indexPath) as! ListActivityTableViewCell

    cell.title.text = listActivity[indexPath.row].pathImage
    return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let segueIdentifier: String
    switch indexPath.section {
    case 0:
        segueIdentifier = "webView"
    case 1:
        segueIdentifier = "ujian"
    default:
        segueIdentifier = ""
    }
    self.performSegue(withIdentifier: segueIdentifier, sender: self)

}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    let indexPath = self.tableView.indexPathForSelectedRow

    switch indexPath?.section {
    case 0:
        let vc = segue.destination as! DetailPdfViewController
        let user = listActivity[(indexPath?.row)!]
        vc.webSite = user.pathPdf
    default:
        break
    }
}
func fetchData(){
    DispatchQueue.main.async {
        let url = URLs.listActivity
        guard let user = helper.getApiUser() else{ return }
        guard let token = helper.getApiToken() else{ return }
        guard let kodePelaksanaan = helper.getKodePelaksanaan() else{ return }

        print(kodePelaksanaan)

        let parameter =  [
            "request" : "{\"requestMethod\":\"detail_selflearning\",\"user\":\"\(user)\",\"kode_pelaksanaan\":\"\(kodePelaksanaan)\"}"
        ]

        let headers: HTTPHeaders = [
            "Content-Type" : "application/x-www-form-urlencoded",
            "Authorization" : "Bearer \(token)"
        ]

        Alamofire.request(url, method: .post, parameters: parameter, encoding: URLEncoding.default, headers: headers).responseJSON(completionHandler: { (response) in

            switch response.result{
            case .success(let value):
                let json = JSON(value)

                let data1 = json["responseData"]["data"]["materi_selflearning"]

                for item in data1.array!{

                    if (item["jenis_materi"] == "2" || item["jenis_materi"] == "3" || item["jenis_materi"] == "99"){

                        let image_detail = item["nama_pelaksanaan"].stringValue
                        let pdfDetail = item["path_file"].stringValue
                        let listActivitied = ListActivity(pathImage: image_detail, pathPdf: pdfDetail)

                        self.listActivity.append(listActivitied)
                        self.tableView.reloadData()
                    }

                }

            case .failure(let error):
                print(error)
            }
        })

    }      
    }
    }

this the output I get in second view controller:

  nilai kode pelaksanaan: ELR2018050004

I want get the output in second view controller like this:

  nilai kode pelaksanaan: ELR2018120005
  nilai kode pelaksanaan: ELR2018120004
  nilai kode pelaksanaan: ELR2018120003
  nilai kode pelaksanaan: ELR2018120001
  nilai kode pelaksanaan: ELR2018050004

this my class helper:

  class helper: NSObject {
     class func saveKodePelaksanaan(kode_pelaksanaan: String){
    let def = UserDefaults.standard
    def.set(kode_pelaksanaan, forKey: "kode_pelaksanaan")
    def.synchronize()
   }

  class func getKodePelaksanaan() -> String? {
    let def = UserDefaults.standard
    return def.object(forKey: "kode_pelaksanaan") as? String
    }
  }
amin
  • 313
  • 1
  • 10
edo oktarifa
  • 63
  • 1
  • 13
  • 1
    You are saving the items (String value) to `UserDefaults` one by one by using the same `key`. So when you save the 2nd string, it replaces the previous string because of the same key. And for this reason the value for the key `"kode_pelaksanaan"` in your `UserDefaults` is the last string from your array. So you need to save the `Array` as a **whole** and retrieve the `Array` as a whole, otherwise you won't get same value. – nayem Dec 18 '18 at 06:30
  • so how to save array as a whole and retrieve the array as a whole? – edo oktarifa Dec 18 '18 at 06:42
  • 1
    Possible duplicate of [save and retrieve array to user default using swift](https://stackoverflow.com/questions/53826138/save-and-retrieve-array-to-user-default-using-swift) – Sachin Raut Dec 18 '18 at 06:49

2 Answers2

0

Hope this message find you well

You are trying to save only a string as shown in below function :-

class func saveKodePelaksanaan(kode_pelaksanaan: String){
let def = UserDefaults.standard
def.set(kode_pelaksanaan, forKey: "kode_pelaksanaan")
def.synchronize()
}

but It should have dictionary or array in function parameters like following

class func saveKodePelaksanaan(kode_pelaksanaan: array){
 let def = UserDefaults.standard
 def.set(kode_pelaksanaan, forKey: "kode_pelaksanaan")
 def.synchronize()
}

// Or

class func saveKodePelaksanaan(kode_pelaksanaan: dictionary){
 let def = UserDefaults.standard
 def.set(kode_pelaksanaan, forKey: "kode_pelaksanaan")
 def.synchronize()
}

also you should call helper class function when you your for loop is finished not when loop is execute it self as follwing:-

    func fetchData(){
    DispatchQueue.main.async {
        let url = URLs.listImage
        guard let user = helper.getApiUser() else{ return }

        guard let token = helper.getApiToken() else{ return }

        let parameter  = [
            "request": "{\"requestMethod\":\"list_selflearning\",\"user\":\"\(user)\"}"

        ]

        let headers: HTTPHeaders = [
            "Content-Type" : "application/x-www-form-urlencoded",
            "Authorization" : "Bearer \(token)"
        ]

        Alamofire.request(url, method: .post, parameters: parameter, headers: headers).responseJSON(completionHandler: { (response) in
            switch response.result{
            case .success(let value):
                let json = JSON(value)
                if let data = json["responseData"].array{
                    for item in data{
                        let images = item["image_detail"]["path_image"].string
                        let namaPelaksana = item["nama_pelaksanaan"].string

                        let listData = ListSelfLearningModel(listImage: images!, labelName: namaPelaksana!)
                        self.listSelfLearning.append(listData)

                    }

                    // Changes are made here
                    helper.saveKodePelaksanaan(kode_pelaksanaan: self.listSelfLearning)

                }

                self.collectionView.reloadData()

            case .failure(let error):
                print(error)
            }
        })
    }
}

If you have any problem please share with me,I will update as soon as possible.

harman virk
  • 7
  • 1
  • 3
  • i get error i change userDefault like this: class func saveKodePelaksanaan(kode_pelaksanaan: Array){ let def = UserDefaults.standard def.set(kode_pelaksanaan, forKey: "kode_pelaksanaan") def.synchronize() } // Changes are made here helper.saveKodePelaksanaan(kode_pelaksanaan: self.listSelfLearning) – edo oktarifa Dec 18 '18 at 07:01
  • this the error: as an NSUserDefaults/CFPreferences value for key kode_pelaksanaan 2018-12-18 13:57:13.124702+0700 BRISMART[4211:140578] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to insert non-property list object ( "BRISMART.ListSelfLearningModel(listImage: \"http://1.142.17.3/edu/uploads/ms_image/brismart_logo.png\", labelName: \"SIT\")" ) for key kode_pelaksanaan' – edo oktarifa Dec 18 '18 at 07:05
  • Dear edo oktarifa that is because you pass array of Modal ( ListSelfLearningModel ). can you send me your project so that I can do all required changes and add comment on each line, else you can pass your array to dictionary and save that dictionary. – harman virk Dec 18 '18 at 08:24
  • sure, how i can send to you.? by email or github? – edo oktarifa Dec 18 '18 at 08:41
  • my email is harmansjpp@gmail.com or you can share with me on github as well as my github id is harmansjpp@gmail.com and my github username is harmandeep97 waiting for project – harman virk Dec 18 '18 at 10:04
  • i have send it to your gmail : harmansjpp@gmail.com, please help me. thank you – edo oktarifa Dec 19 '18 at 03:40
0

You can use SwiftyUserDefaults

MoeinDeveloper
  • 251
  • 1
  • 2
  • 11