This will be my first question on StackOverflow and my first question posed on Swift 3; I'm a beginner and perhaps biting off more than I can chew, however...
I am trying to create a class which will assist in creating menu items (the class is called 'MenuItems') to populate into a dynamic table in my IOS application. I have created the bulk of the class which identifies from the data passed to it what the headers are and how many of each type will be separated into sections within the table. I am now at the stage of trying to make the class more generic so it will work for different data structures that I may want to populate into a similar table in the future.
The data that I wish to have in the table comes from a structure that is in its own swift file. It looks like this:
struct EquipmentStruct {
var name : String!
var serialNumber : String?
var alias : String?
var image : UIImage?
}
I have an array of type EquipmentStruct which, for the short term, is initialised in my tableViewController file (it will not stay here in the future) and I hope to create a public function in my MenuItems class which will allow me to add an item to the table as necessary
func addItem(item, dataType) // types for item and dataType are part of my question
In designing this function I discover my questions:
How do I pass a variable of type EquipmentStruct to an instance of my MenuItems class so I can add it to my table - please note, all I am asking is for guidance on how to complete the addItem method and not the rest of the class. In my mind I want to do something like:
var dataArray : [EquipmentStruct] =
[EquipmentStruct(name: "SA80", serialNumber:"01234-56-789", alias: "29", image: #imageLiteral(resourceName: "SA80")),
EquipmentStruct(name: "LSW", serialNumber:"11111-22-333-4444", alias: "98", image: #imageLiteral(resourceName: "LSW"))]
var tableMenuItems = MenuItems() // create instance of class MenuItems
override func viewDidLoad() {
super.viewDidLoad()
for var itemNumber in 0..<dataArray.count{
tableMenuItems.addItem(item: generalHoldingsDataArray[itemNumber], dataType: EquipmentStruct)
}
The addItems method prototype would therefore be something like:
// Add new item of type 'dataType' to MenuItems.tableDataArray
// Store tableDataArrayType for use throughout the class
//
func addItem(item: [Something], dataType: SomeVariableType){
if let newItem = item as! dataType{ // cast the variable received to its type
tableDataArrayType = dataType
tableDataArray.append(newItem)
}
}
Is this a good way of doing things?
Is there a simpler way of doing what I'm trying to do?
If I continue down this path, what issues might I come up against in the future?
Your assistance would be gratefully appreciated.
Kind regards
A table view is supposed to hold only one type of stuff as model. A single table view is not designed to show info about an EquipmentStruct, a SomeOtherStruct and maybe 3 Foos. You have to generalize all these into one single type.
Another possibility is that you want to create a MenuItems type that can create a table view that shows EquipmentStructs, a table view that shows SomeOtherStructs, basically a table view that shows whatever type you like. If this is the case, you should use generics.
Make the MenuItems class like this:
class MenuItems<T : SomeProtocol> {
var tableDataArray: [T] = []
func addItem(_ newItem: T) {
tableDataArray.append(newItem)
}
// ...
// since you just need guidance on creating addItems method, figure the rest yourself please! XD
}
To create a table view that shows EquipmentStructs,
let tableMenuItems = MenuItems<EquipmentStruct>()
To create a table view that shows SomeOtherStructs,
let tableMenuItems = MenuItems<SomeOtherStruct>()
Notice the SomeProtocol in the first line? That defines what properties/methods a type should have, in order to be shown in a table view. A possible SomeProtocol might be:
protocol SomeProtocol {
var displayTitle: String { get }
var displaySubtitle: String? { get }
var displayImage: UIImage? { get }
}
This just ensures that the type you want to display in the table view have properties called displayTitle, displaySubtitle, displayImage. You can use these properties in your MenuItems class to set the table view cells' appearences.
Related
Sorry for the messy formatting: tried to correct it, improved it a bit.
This is a struct that I'm trying to encode. It does conform to Codable now, but any inclusion of the rest of the content, always based on ObjectIdentifiers, blows up, so I conclude they present a problem for encoding.
What I'm trying to accomplish is to be able to restore the entity relationships between a number of classes when I decode elsewhere. I don't see a way to get the JSON Encoder to see those relationships, so maybe there's a way to do that.
But in lieu I initialize the struct with the basic data. This is the simplest such struct, with only a name property in the class, but it also grabs the id of the project the Block belongs to, and attempts to initialize that value.
Afterwards, I loop through the different entities, and update the structs that are initialized with the Array values for comps, gitpaths, inProject, and selectionThreads.
So that's what I'm doing and the goal. The stumbling block is encoding the ObjectIdentifiers. What am I missing?
struct ProjectBlock : Codable {
/*
var comps : Array<ObjectIdentifier>?
var gitpaths : Array<ObjectIdentifier>?
var inProject : ObjectIdentifier?
var selectionThreads : Array<ObjectIdentifier>?
*/
var name : String
/*
var exportObjID : ObjectIdentifier
*/
init(block : Blocks) {
name = block.name!
/*
exportObjID = block.id
inProject = block.inProject!.id
*/
}
enum CodingKeys: String, CodingKey {
/*
case comps = "comps"
case gitpaths = "gitpaths"
case inProject = "inProject"
case selectionThreads = "selectionThreads"
case exportObjID = "exportObjID"
*/
case name = "name"
}
}
hope I can get some valued assistance with a little issue I'm trying to work.
I've got an API endpoint which is sending data with the following request schema:
{
"type": String,
"coordinates": [
0.949492,
48.77163
]
}
As can be seen; the coordinates from the search are provided as two INT values, without parameters.
I'm trying to create an automated test for this, and I've put the above in a data class so it can be used all over the suite as-needed.
My data class is currently looking like the below example, but I don't know how to properly define a list for coordinates without a val or var parameter. I've defined it as a var called "list" for now so it stops throwing compilation errors. How should I be representing this list of coordinates?
data class SearchRequest(
val type: String,
val coordinates: List<Coordinates>
)
data class Coordinates(
var list: Int
)
The second parameter is a list of Float values, there is no need to create a separate class for that, Float can be used:
data class SearchRequest(
val type: String,
val coordinates: List<Float>
)
In addition to the answers above, you can also download a plugin from android studio that does this for you by just pasting the API's JSON format. The plugin name is JSON to Kotlin class converter, I think.👍🏻
Currently I am working on a MacOS financial market trading application that could receive 10-20 websocket messages per second containing JSON data. For now, let's assume that once the data has been displayed in a table and a new message has been received, the previous data is no longer needed. What would be the recommended, and most efficient way to get the data into the table, and to keep updating it as fast as possible?
I have the websocket connection setup and working properly (using SocketRocket. Data is coming in as it should. But I really don't want to continue further without having a better understanding of the most efficient way to present that data into the table. I was reading about DictionaryArrayController, and maybe utilizing a database library, but I think the latter would would only add unnecessary overhead for what I am trying to do.
Below is a sample of the data that I am receiving.
{
"id":"5267",
"pt":"T",
"ls":["1"],
"lp":["11968"],
"t":["1571824228"],
"v":"133758",
"h":"11981",
"l":"11928",
"bp":["0","1","2","3","4","5","6","7","8","9"],
"bs":["14","73","87","66","74","96","98","85","111","104"],
"ap":["1","2","3","4","5","6","7","8","9","10"],
"as":["69","67","62","124","89","105","97","107","113","124"]
}
The only values that I will need to display & update to the table will be coming from keys: "ls" "lp" "v" "h" "l" "bs" "as"
I don't really need a detailed coded response, but I'd never refuse it, either. Mainly just looking for thoughts so I don't have to switch to a different way, later.
I'll also attach an screen capture of an Excel file showing about how the cells will be laid out. screenshot of desired layout
Have you tried using a JSON decoder, built in to Swift?
Create an appropriate using model, using the Decodable protocol. The property names and data types must match the incoming JSON exactly
struct IncomingData: Decodable {
{
let ls: [String],
let lp: [String],
let h: String,
let as: [String]
}
The set up the parse like this:
func parseJSON(_ incomingData: Data) -> IncomingData? {
let decoder = JSONDecoder()
do {
let parsedData = try decoder.decode(IncomingData.self, from: incomingData)
print("as: \(as)"
return parsedData
}
catch {
self.delegate?.didFailWithError(error: error)
return nil
}
}
I am newbie in kotlin and I try to copy a JSON structure to another one in an efficient way.
I have an API called getData() how send back a data structure defined as below:
data class DataA(
var id: String,
var cartItems: List<CartItem>,
}
When the getData sent back the DataA structure, I have to map or translate it to another structure defined as below:
data class DataB(
var cartItems: List<CartItem>,
}
Is there an easy way to do it? I know that kotlin can easily encapsulate calls to make it nice.
Thanks
Since you simply need to convert an instance of DataA to an instance of DataB, what you can do is DataB(dataA.cartItems), where dataA is the instance of DataA.
Note, however, that if for any reason you modify any item of cartItems from dataA, this change will be reflected also to dataB, since they share the same list object.
I am new to typescript,
I want to accept a JSON data whose size is no fix...
After accepting a data i want it to show in table form...
My JSON data will be like
[{"regionID":1 "regionname":"Can"},
{"regionID":1 "regionname":"Cen"}]
and the field if that table is not editable...
Well, the typescript way to do it would be to create a class, let's call it region:
Class Region {
regionId: number;
regionName: string;
constructor(id, name) {
regionId = id;
regionName = name;
}
}
then you should convert the result JSON into array of that class.
regions: Region[] = new Array<Region>();
JSON.parse(myJson).forEach(item => {
regions.push(new Region(item));
});
Showing it in a table should be very similar to how you work in javascript, typescript should not be an issue for that matter (you might want to describe it in a different question, as it seems of topic)