How to declare a variable with two possible types












0















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










share|improve this question




















  • 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
















0















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










share|improve this question




















  • 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














0












0








0


1






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










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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














  • 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












1 Answer
1






active

oldest

votes


















1














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.






share|improve this answer





















  • 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











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
});


}
});














draft saved

draft discarded


















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









1














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.






share|improve this answer





















  • 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














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.






share|improve this answer





















  • 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








1







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.






share|improve this answer















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.







share|improve this answer














share|improve this answer



share|improve this answer








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














  • 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


















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

Berounka

Different font size/position of beamer's navigation symbols template's content depending on regular/plain...

Sphinx de Gizeh