How to declare a variable with two possible types
I have two Core Data entities
which populate a UITableView
with 2 sections, one entity for each section. When the user taps on a table row, they are directed to another view where the data of that row is sent. It is currently implemented like this:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "editValue") {
let secondViewController = segue.destination as! EditValuesViewController
if send_array_inc.isEmpty {
secondViewController.send_array_exp = send_array_exp
} else if send_array_exp.isEmpty {
secondViewController.send_array_inc = send_array_inc
}
}
}
The Question:
Since there are two entities, there are two possible types (Income
and Expenses
) for the data being sent into the next view. How can I use that data in the next view with one variable? I am doing the below in ViewDidLoad
but the scope of send_array
remains within that function. How can I make send_array
available outside?
if send_array_inc.isEmpty {
var send_array = [Expenses]()
send_array = send_array_exp
} else if send_array_exp.isEmpty {
var send_array = [Income]()
send_array = send_array_inc
}
I ideally want to do this without creating a separate view for each entity result but I am open to refactor if another solution would be better and realistic. Thank you
swift uitableview core-data scope
add a comment |
I have two Core Data entities
which populate a UITableView
with 2 sections, one entity for each section. When the user taps on a table row, they are directed to another view where the data of that row is sent. It is currently implemented like this:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "editValue") {
let secondViewController = segue.destination as! EditValuesViewController
if send_array_inc.isEmpty {
secondViewController.send_array_exp = send_array_exp
} else if send_array_exp.isEmpty {
secondViewController.send_array_inc = send_array_inc
}
}
}
The Question:
Since there are two entities, there are two possible types (Income
and Expenses
) for the data being sent into the next view. How can I use that data in the next view with one variable? I am doing the below in ViewDidLoad
but the scope of send_array
remains within that function. How can I make send_array
available outside?
if send_array_inc.isEmpty {
var send_array = [Expenses]()
send_array = send_array_exp
} else if send_array_exp.isEmpty {
var send_array = [Income]()
send_array = send_array_inc
}
I ideally want to do this without creating a separate view for each entity result but I am open to refactor if another solution would be better and realistic. Thank you
swift uitableview core-data scope
1
Consider using only one entity and adding a type column to differentiate between expenses and income. Another option to consider is to use inheritance in Core Data and to define the common fields that you want to edit in your view controller in the parent entity.
– Mike Taverne
Nov 24 '18 at 0:26
I really like that first idea Mike, Thanks man!!
– Nouman
Nov 24 '18 at 21:19
add a comment |
I have two Core Data entities
which populate a UITableView
with 2 sections, one entity for each section. When the user taps on a table row, they are directed to another view where the data of that row is sent. It is currently implemented like this:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "editValue") {
let secondViewController = segue.destination as! EditValuesViewController
if send_array_inc.isEmpty {
secondViewController.send_array_exp = send_array_exp
} else if send_array_exp.isEmpty {
secondViewController.send_array_inc = send_array_inc
}
}
}
The Question:
Since there are two entities, there are two possible types (Income
and Expenses
) for the data being sent into the next view. How can I use that data in the next view with one variable? I am doing the below in ViewDidLoad
but the scope of send_array
remains within that function. How can I make send_array
available outside?
if send_array_inc.isEmpty {
var send_array = [Expenses]()
send_array = send_array_exp
} else if send_array_exp.isEmpty {
var send_array = [Income]()
send_array = send_array_inc
}
I ideally want to do this without creating a separate view for each entity result but I am open to refactor if another solution would be better and realistic. Thank you
swift uitableview core-data scope
I have two Core Data entities
which populate a UITableView
with 2 sections, one entity for each section. When the user taps on a table row, they are directed to another view where the data of that row is sent. It is currently implemented like this:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "editValue") {
let secondViewController = segue.destination as! EditValuesViewController
if send_array_inc.isEmpty {
secondViewController.send_array_exp = send_array_exp
} else if send_array_exp.isEmpty {
secondViewController.send_array_inc = send_array_inc
}
}
}
The Question:
Since there are two entities, there are two possible types (Income
and Expenses
) for the data being sent into the next view. How can I use that data in the next view with one variable? I am doing the below in ViewDidLoad
but the scope of send_array
remains within that function. How can I make send_array
available outside?
if send_array_inc.isEmpty {
var send_array = [Expenses]()
send_array = send_array_exp
} else if send_array_exp.isEmpty {
var send_array = [Income]()
send_array = send_array_inc
}
I ideally want to do this without creating a separate view for each entity result but I am open to refactor if another solution would be better and realistic. Thank you
swift uitableview core-data scope
swift uitableview core-data scope
edited Nov 23 '18 at 14:03
Nouman
asked Nov 23 '18 at 13:57
NoumanNouman
92212
92212
1
Consider using only one entity and adding a type column to differentiate between expenses and income. Another option to consider is to use inheritance in Core Data and to define the common fields that you want to edit in your view controller in the parent entity.
– Mike Taverne
Nov 24 '18 at 0:26
I really like that first idea Mike, Thanks man!!
– Nouman
Nov 24 '18 at 21:19
add a comment |
1
Consider using only one entity and adding a type column to differentiate between expenses and income. Another option to consider is to use inheritance in Core Data and to define the common fields that you want to edit in your view controller in the parent entity.
– Mike Taverne
Nov 24 '18 at 0:26
I really like that first idea Mike, Thanks man!!
– Nouman
Nov 24 '18 at 21:19
1
1
Consider using only one entity and adding a type column to differentiate between expenses and income. Another option to consider is to use inheritance in Core Data and to define the common fields that you want to edit in your view controller in the parent entity.
– Mike Taverne
Nov 24 '18 at 0:26
Consider using only one entity and adding a type column to differentiate between expenses and income. Another option to consider is to use inheritance in Core Data and to define the common fields that you want to edit in your view controller in the parent entity.
– Mike Taverne
Nov 24 '18 at 0:26
I really like that first idea Mike, Thanks man!!
– Nouman
Nov 24 '18 at 21:19
I really like that first idea Mike, Thanks man!!
– Nouman
Nov 24 '18 at 21:19
add a comment |
1 Answer
1
active
oldest
votes
Make your two types of data objects conform to a shared protocol. Make the destination view controller's send_array
be an object conforming to that protocol.
In your EditValuesViewController's code, interrogate the send_array
to figure out which type of data object was passed in.
Edit:
Define a protocol
@protocol dataArrayProtocol {
var dataArray: Array
}
Define 2 structs that conform to that protocol
struct ExpensesArrayStruct: dataArrayProtocol {
var dataArray: [Expenses]
}
struct IncomeArrayStruct: dataArrayProtocol {
var dataArray: [Income]
}
give your EditValuesViewController
a property that conforms to that protocol
class EditValuesViewController: UIViewController {
var dataArrayStruct: dataArrayProtocol
}
And your prepare(for:sender)
method
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "editValue") {
let secondViewController = segue.destination as! EditValuesViewController
if send_array_inc.isEmpty {
secondViewController.dataArrayStruct = ExpensesArrayStruct(dataArray: send_array_exp)
} else if send_array_exp.isEmpty {
secondViewController.dataArrayStruct = IncomeArrayStruct(dataArray: send_array_inc)
}
}
}
And to handle the data:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let expensesStruct = dataArrayStruct as? ExpensesArrayStruct {
//deal with expenses array
} else if let incomeStruct = dataArrayStruct as? IncomeArrayStruct {
//deal with income array
}
}
Note that I banged this code out in the SO editor and have not tried to compile it. I may have made some minor errors. It should give you the idea though.
1
It's harder to make generic collections like arrays conform to a shared protocol. You could wrap your array in a struct and make the struct conform to your protocol.
– Duncan C
Nov 23 '18 at 14:20
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53448053%2fhow-to-declare-a-variable-with-two-possible-types%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Make your two types of data objects conform to a shared protocol. Make the destination view controller's send_array
be an object conforming to that protocol.
In your EditValuesViewController's code, interrogate the send_array
to figure out which type of data object was passed in.
Edit:
Define a protocol
@protocol dataArrayProtocol {
var dataArray: Array
}
Define 2 structs that conform to that protocol
struct ExpensesArrayStruct: dataArrayProtocol {
var dataArray: [Expenses]
}
struct IncomeArrayStruct: dataArrayProtocol {
var dataArray: [Income]
}
give your EditValuesViewController
a property that conforms to that protocol
class EditValuesViewController: UIViewController {
var dataArrayStruct: dataArrayProtocol
}
And your prepare(for:sender)
method
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "editValue") {
let secondViewController = segue.destination as! EditValuesViewController
if send_array_inc.isEmpty {
secondViewController.dataArrayStruct = ExpensesArrayStruct(dataArray: send_array_exp)
} else if send_array_exp.isEmpty {
secondViewController.dataArrayStruct = IncomeArrayStruct(dataArray: send_array_inc)
}
}
}
And to handle the data:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let expensesStruct = dataArrayStruct as? ExpensesArrayStruct {
//deal with expenses array
} else if let incomeStruct = dataArrayStruct as? IncomeArrayStruct {
//deal with income array
}
}
Note that I banged this code out in the SO editor and have not tried to compile it. I may have made some minor errors. It should give you the idea though.
1
It's harder to make generic collections like arrays conform to a shared protocol. You could wrap your array in a struct and make the struct conform to your protocol.
– Duncan C
Nov 23 '18 at 14:20
add a comment |
Make your two types of data objects conform to a shared protocol. Make the destination view controller's send_array
be an object conforming to that protocol.
In your EditValuesViewController's code, interrogate the send_array
to figure out which type of data object was passed in.
Edit:
Define a protocol
@protocol dataArrayProtocol {
var dataArray: Array
}
Define 2 structs that conform to that protocol
struct ExpensesArrayStruct: dataArrayProtocol {
var dataArray: [Expenses]
}
struct IncomeArrayStruct: dataArrayProtocol {
var dataArray: [Income]
}
give your EditValuesViewController
a property that conforms to that protocol
class EditValuesViewController: UIViewController {
var dataArrayStruct: dataArrayProtocol
}
And your prepare(for:sender)
method
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "editValue") {
let secondViewController = segue.destination as! EditValuesViewController
if send_array_inc.isEmpty {
secondViewController.dataArrayStruct = ExpensesArrayStruct(dataArray: send_array_exp)
} else if send_array_exp.isEmpty {
secondViewController.dataArrayStruct = IncomeArrayStruct(dataArray: send_array_inc)
}
}
}
And to handle the data:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let expensesStruct = dataArrayStruct as? ExpensesArrayStruct {
//deal with expenses array
} else if let incomeStruct = dataArrayStruct as? IncomeArrayStruct {
//deal with income array
}
}
Note that I banged this code out in the SO editor and have not tried to compile it. I may have made some minor errors. It should give you the idea though.
1
It's harder to make generic collections like arrays conform to a shared protocol. You could wrap your array in a struct and make the struct conform to your protocol.
– Duncan C
Nov 23 '18 at 14:20
add a comment |
Make your two types of data objects conform to a shared protocol. Make the destination view controller's send_array
be an object conforming to that protocol.
In your EditValuesViewController's code, interrogate the send_array
to figure out which type of data object was passed in.
Edit:
Define a protocol
@protocol dataArrayProtocol {
var dataArray: Array
}
Define 2 structs that conform to that protocol
struct ExpensesArrayStruct: dataArrayProtocol {
var dataArray: [Expenses]
}
struct IncomeArrayStruct: dataArrayProtocol {
var dataArray: [Income]
}
give your EditValuesViewController
a property that conforms to that protocol
class EditValuesViewController: UIViewController {
var dataArrayStruct: dataArrayProtocol
}
And your prepare(for:sender)
method
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "editValue") {
let secondViewController = segue.destination as! EditValuesViewController
if send_array_inc.isEmpty {
secondViewController.dataArrayStruct = ExpensesArrayStruct(dataArray: send_array_exp)
} else if send_array_exp.isEmpty {
secondViewController.dataArrayStruct = IncomeArrayStruct(dataArray: send_array_inc)
}
}
}
And to handle the data:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let expensesStruct = dataArrayStruct as? ExpensesArrayStruct {
//deal with expenses array
} else if let incomeStruct = dataArrayStruct as? IncomeArrayStruct {
//deal with income array
}
}
Note that I banged this code out in the SO editor and have not tried to compile it. I may have made some minor errors. It should give you the idea though.
Make your two types of data objects conform to a shared protocol. Make the destination view controller's send_array
be an object conforming to that protocol.
In your EditValuesViewController's code, interrogate the send_array
to figure out which type of data object was passed in.
Edit:
Define a protocol
@protocol dataArrayProtocol {
var dataArray: Array
}
Define 2 structs that conform to that protocol
struct ExpensesArrayStruct: dataArrayProtocol {
var dataArray: [Expenses]
}
struct IncomeArrayStruct: dataArrayProtocol {
var dataArray: [Income]
}
give your EditValuesViewController
a property that conforms to that protocol
class EditValuesViewController: UIViewController {
var dataArrayStruct: dataArrayProtocol
}
And your prepare(for:sender)
method
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "editValue") {
let secondViewController = segue.destination as! EditValuesViewController
if send_array_inc.isEmpty {
secondViewController.dataArrayStruct = ExpensesArrayStruct(dataArray: send_array_exp)
} else if send_array_exp.isEmpty {
secondViewController.dataArrayStruct = IncomeArrayStruct(dataArray: send_array_inc)
}
}
}
And to handle the data:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let expensesStruct = dataArrayStruct as? ExpensesArrayStruct {
//deal with expenses array
} else if let incomeStruct = dataArrayStruct as? IncomeArrayStruct {
//deal with income array
}
}
Note that I banged this code out in the SO editor and have not tried to compile it. I may have made some minor errors. It should give you the idea though.
edited Nov 23 '18 at 14:31
answered Nov 23 '18 at 14:05
Duncan CDuncan C
92.4k13114196
92.4k13114196
1
It's harder to make generic collections like arrays conform to a shared protocol. You could wrap your array in a struct and make the struct conform to your protocol.
– Duncan C
Nov 23 '18 at 14:20
add a comment |
1
It's harder to make generic collections like arrays conform to a shared protocol. You could wrap your array in a struct and make the struct conform to your protocol.
– Duncan C
Nov 23 '18 at 14:20
1
1
It's harder to make generic collections like arrays conform to a shared protocol. You could wrap your array in a struct and make the struct conform to your protocol.
– Duncan C
Nov 23 '18 at 14:20
It's harder to make generic collections like arrays conform to a shared protocol. You could wrap your array in a struct and make the struct conform to your protocol.
– Duncan C
Nov 23 '18 at 14:20
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53448053%2fhow-to-declare-a-variable-with-two-possible-types%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Consider using only one entity and adding a type column to differentiate between expenses and income. Another option to consider is to use inheritance in Core Data and to define the common fields that you want to edit in your view controller in the parent entity.
– Mike Taverne
Nov 24 '18 at 0:26
I really like that first idea Mike, Thanks man!!
– Nouman
Nov 24 '18 at 21:19