ObjectMapper - initialize object IOS - ios

Simple thing that is giving me a headache - how to initialize an object that conforms to mappable protocol, without any JSON yet.
What I would like to do, is simply initialise empty User object in code like this:
let user = User()
however that gives me error:
"missing argument for parameter #1 in call"
I was able to do it in version 0.14 with swift 1.2, but now it doesnt work. Do you guys know how to do it now in swift 2 and new Object Mapper ? (I know how to initialize it with json etc, I just want to initialize that object for other purposes and I cant figure out how)
class User: Mappable {
var username: String?
var age: Int?
var weight: Double!
var array: [AnyObject]?
var dictionary: [String : AnyObject] = [:]
var bestFriend: User? // Nested User object
var friends: [User]? // Array of Users
var birthday: NSDate?
required init?(_ map: Map) {
}
// Mappable
func mapping(map: Map) {
username <- map["username"]
age <- map["age"]
weight <- map["weight"]
array <- map["arr"]
dictionary <- map["dict"]
bestFriend <- map["best_friend"]
friends <- map["friends"]
birthday <- (map["birthday"], DateTransform())
}
}
please help!

The following should work:
class User: NSObject, Mappable {
var username: String?
var age: Int?
var weight: Double!
var array: [AnyObject]?
var dictionary: [String : AnyObject] = [:]
var bestFriend: User? // Nested User object
var friends: [User]? // Array of Users
var birthday: NSDate?
override init() {
super.init()
}
convenience required init?(_ map: Map) {
self.init()
}
// Mappable
func mapping(map: Map) {
username <- map["username"]
age <- map["age"]
weight <- map["weight"]
array <- map["arr"]
dictionary <- map["dict"]
bestFriend <- map["best_friend"]
friends <- map["friends"]
birthday <- (map["birthday"], DateTransform())
}
}

Fixed version of above answer:
init() {}
required convenience init?(_ map: Map) { self.init() }

Related

Alamofire ObjectMapper - Extract common fields from all models and map them

There are few fields common in all models returned by api. But they don't come as a separate object. They are there among other fields.
Example of two models :
Event :
[
{
"event":{
"id":3,
"company_id":18,
"archived":false,
"created_by":229,
"updated_by":229,
"owner_id":229,
"subject":"",
"start_date":null,
"end_date":null,
"name":null,
"name_class_name":"",
"related_to":null,
"related_to_class_name":"",
"status":"",
"created_at":"2018-05-07T01:59:38.921-04:00",
"updated_at":"2018-05-07T01:59:38.921-04:00",
"custom_nf":false
}
}
]
Opportunity :
[
{
"opportunity":{
"id":4,
"company_id":18,
"archived":false,
"created_by":229,
"updated_by":229,
"owner_id":229,
"account_id":null,
"name":"",
"lead_source":"",
"amount":null,
"close_date":null,
"probability":null,
"stage":"",
"created_at":"2018-05-07T01:49:55.441-04:00",
"updated_at":"2018-05-07T01:49:55.441-04:00"
}
}
]
As shown, initial fields are common in both (all) models - id, company_id, archived, created_by and so on.
There are tons of projects I have worked with ObjectMapper but didn't encounter this before. I am fully aware of handling nested models, but this is a different case.
Though I can easily handle this by repeating all common fields in all models. But this doesn't sound good.
What I am looking is a way I can create a separate model class with all common fields. But the question is - how would I map that with api response using ObjectMapper ?
Just as an example, this is how I have created Opportunity model :
import UIKit
import ObjectMapper
class Opportunity: NSObject, Mappable {
var id: Int?
var companyId: Int?
var archived: Int?
var createdBy: Int?
var updatedBy: Int?
var ownerId: Int?
var accountId: Int?
var name: String?
var leadSource: String?
var amount: String?
var closeDate: String?
var probability: String?
var stage: String?
var createdAt: String?
var updatedAt: String?
required init?(map: Map) {
}
func mapping(map: Map) {
self.id <- map["id"]
self.companyId <- map["company_id"]
self.archived <- map["archived"]
self.createdBy <- map["created_by"]
self.updatedBy <- map["updated_by"]
self.ownerId <- map["owner_id"]
self.accountId <- map["account_id"]
self.name <- map["name"]
self.leadSource <- map["lead_source"]
self.amount <- map["amount"]
self.closeDate <- map["close_date"]
self.probability <- map["probability"]
self.stage <- map["stage"]
self.createdAt <- map["created_at"]
self.updatedAt <- map["updated_at"]
}
}
You can create base entity and put there common fields.
Example:
import UIKit
import ObjectMapper
class BaseEntity: NSObject, Mappable {
var id: Int?
var companyId: Int?
var archived: Int?
var createdBy: Int?
var updatedBy: Int?
var ownerId: Int?
var name: String?
var createdAt: String?
var updatedAt: String?
required init?(map: Map) {
}
func mapping(map: Map) {
self.id <- map["id"]
self.companyId <- map["company_id"]
self.archived <- map["archived"]
self.createdBy <- map["created_by"]
self.updatedBy <- map["updated_by"]
self.ownerId <- map["owner_id"]
self.name <- map["name"]
self.createdAt <- map["created_at"]
self.updatedAt <- map["updated_at"]
}
}
class Opportunity: BaseEntity {
var accountId: Int?
var leadSource: String?
var amount: String?
var closeDate: String?
var probability: String?
var stage: String?
required init?(map: Map) {
super.init(map: map)
}
override func mapping(map: Map) {
super.mapping(map: map)
self.accountId <- map["account_id"]
self.leadSource <- map["lead_source"]
self.amount <- map["amount"]
self.closeDate <- map["close_date"]
self.probability <- map["probability"]
self.stage <- map["stage"]
}
}
Note: BaseEntity isn't good name, I think you can give better name.

Json parsing Issue using objectmapper library in swift

I am facing issue with parsing response from server side. I get response in this format
1.)
For first image my model class is working fine. In this I don't null
2.)
For second image response my Model class is not working it's giving nil after parsing.In this I get null in array
My Model class for my api response is this
class GetTodayMyKpiResponse: Mappable{
var status: String?
var myKpiMonth: MyKpiMonthResponse?
var myKpiWeek: MyKpiWeekResponse?
required init?(map: Map){
}
func mapping(map: Map) {
status <- map["status"]
myKpiMonth <- map["myKpiMonth"]
myKpiWeek <- map["myKpiWeek"]
}
}
class MyKpiMonthResponse: Mappable{
var myKpiMonthYear: Double?
var myKpiMonthDetailList: [MyKpiMonthDetailResponse]?
var myKpiMonthList: [MyKpiMonthListReponse]?
required init?(map: Map) {
}
func mapping(map: Map) {
myKpiMonthYear <- map["myKpiMonthYear"]
myKpiMonthDetailList <- map["myKpiMonthDetail"]
myKpiMonthList <- map["myKpiMonthList"]
}
}
class MyKpiMonthDetailResponse: Mappable{
var myKpiMonthDetailOutletCode: String?
var myKpiMonthDetailUnitTiers: [String]?
var myKpiMonthDetailTargetUnits: [String]?
var myKpiMonthDetailBonusIncentive: Double?
var myKpiMonthDetailOutletName: String?
var myKpiMonthDetailModelName: [String]?
var myKpiMonthDetailMonth: String?
var myKpiMonthDetailType: Double?
required init?(map: Map) {
}
func mapping(map: Map) {
myKpiMonthDetailOutletCode <- map["myKpiMonthDetailOutletCode"]
myKpiMonthDetailUnitTiers <- map["myKpiMonthDetailUnitTiers"]
myKpiMonthDetailTargetUnits <- map["myKpiMonthDetailTargetUnits"]
myKpiMonthDetailBonusIncentive <- map["myKpiMonthDetailBonusIncentive"]
myKpiMonthDetailOutletName <- map["myKpiMonthDetailOutletName"]
myKpiMonthDetailModelName <- map["myKpiMonthDetailModelName"]
myKpiMonthDetailMonth <- map["myKpiMonthDetailMonth"]
myKpiMonthDetailType <- map["myKpiMonthDetailType"]
}
}
class MyKpiMonthListReponse: Mappable {
var myKpiMonthMaxUnit: Double?
var myKpiMonthDate: String?
var myKpiMonthBonusAmount: Double?
var myKpiMonthActivatedUnit: Double?
var myKpiMonthMinUnit: Double?
var myKpiMonthCurrentUnit: Double?
var myKpiMonthBonusStatus: String?
var myKpiMonthOutletName: String?
var myKpiMonthOutletAddress: String?
required init?(map: Map) {
}
func mapping(map: Map) {
myKpiMonthMaxUnit <- map["myKpiMonthMaxUnit"]
myKpiMonthDate <- map["myKpiMonthDate"]
myKpiMonthBonusAmount <- map["myKpiMonthBonusAmount"]
myKpiMonthActivatedUnit <- map["myKpiMonthActivatedUnit"]
myKpiMonthMinUnit <- map["myKpiMonthMinUnit"]
myKpiMonthCurrentUnit <- map["myKpiMonthCurrentUnit"]
myKpiMonthBonusStatus <- map["myKpiMonthBonusStatus"]
myKpiMonthOutletName <- map["myKpiMonthOutletName"]
myKpiMonthOutletAddress <- map["myKpiMonthOutletAddress"]
}
}
class MyKpiWeekResponse: Mappable{
var myKpiWeekDetail: [MyKpiWeekDetailResponse]?
var myKpiWeekList: [MyKpiWeekListResponse]?
var myKpiWeekYear: Double?
var myKpiWeekMonth: Double?
required init?(map: Map) {
}
func mapping(map: Map) {
myKpiWeekDetail <- map["myKpiWeekDetail"]
myKpiWeekList <- map["myKpiWeekList"]
myKpiWeekYear <- map["myKpiWeekYear"]
myKpiWeekMonth <- map["myKpiWeekMonth"]
}
}
class MyKpiWeekDetailResponse: Mappable{
var myKpiWeekDetailEndDate: String?
var myKpiWeekDetailUnitTiers: [String]?
var myKpiWeekDetailOutletName: String?
var myKpiWeekDetailStartDate: String?
var myKpiWeekDetailType: Double?
var myKpiWeekDetailModelName: [String]?
var myKpiWeekDetailTypeOfReward: String?
var myKpiWeekDetailOutletCode: String?
var myKpiWeekDetailTargetUnits: [String]?
required init?(map: Map) {
}
func mapping(map: Map) {
myKpiWeekDetailEndDate <- map["myKpiWeekDetailEndDate"]
myKpiWeekDetailUnitTiers <- map["myKpiWeekDetailUnitTiers"]
myKpiWeekDetailOutletName <- map["myKpiWeekDetailOutletName"]
myKpiWeekDetailStartDate <- map["myKpiWeekDetailStartDate"]
myKpiWeekDetailType <- map["myKpiWeekDetailType"]
myKpiWeekDetailModelName <- map["myKpiWeekDetailModelName"]
myKpiWeekDetailTypeOfReward <- map["myKpiWeekDetailTypeOfReward"]
myKpiWeekDetailOutletCode <- map["myKpiWeekDetailOutletCode"]
myKpiWeekDetailTargetUnits <- map["myKpiWeekDetailTargetUnits"]
}
}
class MyKpiWeekListResponse: Mappable {
var myKpiWeekBonusStatus: String?
var myKpiWeekEndDate: String?
var myKpiWeekActivatedUnit: Double?
var myKpiWeekStartDate: String?
var myKpiWeekMinUnit: Double?
var myKpiWeekCurrentUnit: Double?
var myKpiWeekOutletName: String?
var myKpiWeekTypeOfReward: String?
var myKpiWeekOutletAddress: String?
var myKpiWeekMaxUnit: Double?
required init?(map: Map) {
}
func mapping(map: Map) {
myKpiWeekBonusStatus <- map["myKpiWeekBonusStatus"]
myKpiWeekEndDate <- map["myKpiWeekEndDate"]
myKpiWeekActivatedUnit <- map["myKpiWeekActivatedUnit"]
myKpiWeekStartDate <- map["myKpiWeekStartDate"]
myKpiWeekMinUnit <- map["myKpiWeekMinUnit"]
myKpiWeekCurrentUnit <- map["myKpiWeekCurrentUnit"]
myKpiWeekOutletName <- map["myKpiWeekOutletName"]
myKpiWeekTypeOfReward <- map["myKpiWeekTypeOfReward"]
myKpiWeekOutletAddress <- map["myKpiWeekOutletAddress"]
myKpiWeekMaxUnit <- map["myKpiWeekMaxUnit"]
}
}
If there is no data available then send empty array not null. Even in myKpiMonthList doesn't contain null array. There is no logic that null value in array at index 2.
You can send empty string or empty array even. Still there is no any logic for the null value.
Either handle all null value from server side else it always crash.

Mapping nested objects from root node is not working

Using ObjectMapper(https://github.com/Hearst-DD/ObjectMapper), I'm doing JSON conversion to Swift Objects. App is crashing while accessing user.profession.
Basically, I do not know how to parse another mappable object inside the model with same JSON map root node I think, I'm doing it wrong. I can't find the documentation for the same anywhere.
JSON dictionary:
user: {
"name": "Dinesh",
"url": "https://dinaraja.me",
"company": "IIINC",
"designation": "Developer"
}
Model:
struct User: Mappable {
var name: String!
var url: URL!
var profession: Profession!
init(_ map: Map) {
name <- map["name"]
url <- map["url"]
profession <- map // FIXME: It's not working. Find out what we do here is right/wrong
}
}
struct Profession: Mappable {
var company: String!
var designation: String!
init(_ map: Map) {
company <- map["company"]
designation <- map["designation"]
}
}
What I did:
let user = Mapper<User>().map(myJSONDictionary)
print(user.profession.company) //FIXME: Crashes here
Any help would be appreciated.
Since profession model its not included directly in user json model you should not use object mapper <- operator in this case. Instead you should initialize new Profession object directly from user mapping function
struct User: Mappable {
var name: String!
var url: URL!
var profession: Profession!
init(map: Map) {
}
mutating func mapping(map: Map) {
name <- map["name"]
url <- map["url"]
profession = Profession(map: map)
}
}
struct Profession: Mappable {
var company: String!
var designation: String!
init(map: Map) {
company <- map["company"]
designation <- map["designation"]
}
mutating func mapping(map: Map) {
company <- map["company"]
designation <- map["designation"]
}
}

ObjectMapper toJson empty

I'm trying to deserialize an object into a JSON dictionary with ObjectMapper but the deserializing functions always return empty objects.
class TimeEntryContainer: Mappable {
//MARK: Properties
var entry: TimeEntryObject = TimeEntryObject()
//MARK: Initializers
init() {}
init(_ issue: Issue, hours: Double, activityId: Int) {
self.entry = TimeEntryObject(issue, hours: hours, activityId: activityId)
}
required init?(map: Map) {
mapping(map: map)
}
//MARK: Private Methods
func mapping(map: Map) {
entry <- map["time_entry"]
}
}
class TimeEntryObject {
//MARK: Properties
var issueId = -1
var projectId = ""
var hours = Double()
var activityId = -1
var comments = ""
//MARK: Initializers
init() {}
init(_ issue: Issue, hours: Double, activityId: Int) {
self.issueId = issue.id
self.projectId = issue.project
self.hours = hours
self.activityId = activityId
}
required init?(map: Map) {
mapping(map: map)
}
//MARK: Private functions
func mapping(map: Map) {
issueId <- map["issue_id"]
projectId <- map["project_id"]
hours <- map["hours"]
activityId <- map["activity_id"]
comments <- map["comments"]
}
}
Here's the part where I fill my TimeEntryContainer object
let timeEntry = TimeEntryContainer()
timeEntry.entry.projectId = (issue?.project)!
timeEntry.entry.activityId = activityId
timeEntry.entry.hours = timeEntered
timeEntry.entry.comments = commentEdit.text ?? ""
let deserialized = Mapper().toJSONString(timeEntry)
print("hours: \(deserialized) ")
Even though the values of my timeEntry object are correctly set, the functions Mapper().toJSONString(), Mapper().toJSON() and even timeEntry.toJSON() and timeEntry.toJSONString() return an empty JSON object / dictionary. I can't find where I went wrong
Your TimeEntryObject must be Mappable. You put in the methods but you didn't declare conformance in the class declaration.
class TimeEntryObject: Mappable
I had same issue, in my case I have Mappable protocol implemented. Biut I had not mapped the variables of class which was giving me empty json.
Posting as just another option/ solution. May help someone in case required.

How to append object in Mappable class(Model). iOS swift

In my app, I'm using Alamofire-ObjectMapper.
I have a [OrderDetailSecond]. now i want to use for loop for this array and when isRxMedicine == 1 i want to add that object in any array so i can display that in my UITableView.
here is my code
this is my model
class OrderDetailSecond: Mappable {
var id : Int?
var isRxMedicine : Int?
var medicineTypeId : String?
var name : String?
var orderId : String?
var price : String?
var quentity : Int?
var strength : String?
required init?(_ map: Map){
}
func mapping(map: Map) {
id <- map["id"]
isRxMedicine <- map["is_rx_medicine"]
medicineTypeId <- map["medicine_type_id"]
name <- map["name"]
orderId <- map["order_id"]
price <- map["price"]
quentity <- map["qty"]
strength <- map["strengh"]
}
}
now here i am trying to add objects in new element
if let Rx_OrderDetail = self.orderdetailInstance, Rx_detail = Rx_OrderDetail.result{
let detailArray = Rx_detail[0].orederDetail
if let orderdata = detailArray
{
for RxDataFilter in orderdata
{
if (RxDataFilter.isRxMedicine == 1)
{
array?.append(RxDataFilter)
}
}
elementConunt = orderdata.count
}
return elementConunt
}
but its not working
Note: orderdata is in form [OrderDetailSecond]

Resources