|
This is my take on iExpense, Day 38: the challenge. Mostly I succeeded, I think, but there remain a few issues. Task 1: Using another currency. I chose Euro by changing the currency code from USD to EUR. Indeed, the currency symbol now is € instead of $. So far, so good. But I noticed a few issues:
Task 2: Styling. I have chosen a very simple styling, green for small amounts, red for large amounts, and blue in between. That works fine. Task 3: Sectioning the display according to type. This was the most challenging. The challenge is twofold: first, get separate sections for Personal and Business, and second, deleting the right expense item. For the first, I created a function that, given a type, returns an array with only those elements that are in that type. In the View I then loop over all types, and create a separate section for each of them with the items in this array. That takes care of the display issue. I found it convenient to create a separate view "ItemView" for this. The second I found trickier. The problem is that the onDelete function gives me an index, but that is the index in the reduced array, not in the full array where I need to delete the element. I have found no built-in way of handling this, so I wrote my own function for it. From the onDelete function I get an indexSet containing one element. This element I use to find the element in the array for the type. This gives me an UUID as id. With this UUID I go into the full expenses array and retrieve the index for the element. Finally, with this index I can remove it with remove(at:). Along the way I applied a few other changes. I have concentrated the declaration of the type names in one place, so as not to have to enter duplicate information with the risk of mistakes. All other uses of the type names are derived from this array definition. An added bonus is that I can now add extra types, such as Family, just by adding them to the array and all functionality takes that now into account. Any comments and suggestions will be welcomed. In particular, how about the issues with the currency field? And is there an easier (maybe built-in) way to delete from a sectioned list?
|
|
Jero makes great progress but would appreciate some feedback:
This is probably the way to do this.
What's NOT the Swifty way is putting this code into a function in your First, ugh, please. Please rename your Second, try to think of views as Consider your delete dilemma. It's not the I would say, the If you want to delete an object from the What happens next? the |
|
Jero has some questions about using Euro.
Here are some wise words I read in John Sundell's blog.
See-> Formatting Numbers Blog Maybe you can get some hints from this post. Please come back and let us know how you implemented your solution. |
|
@Obelix, re: proper place for delete function Thank you for taking the time for this elaborate answer! On your remark about renaming On your second remark, about the proper place for model related functionality: I did not think of that, but just amended the existing removal function from the course, which happened to be inside Therefore I moved it. What I actually did is take matters one step further than your suggestion: in my opinion, even the knowledge that there is a
In this way I was able to keep the The new portions of
The new version of
It was simple to do, it works, and it is indeed much cleaner. Thank you for your insights. |
|
Jero updates his code with skill!
Well done! It's not quite apparent in these challenges and exercises. But one of the benefits of having all your business logic in ONE class is your ability to add that functionality to another program! Once you have a fully functional If you had the "add expense" logic in one
For the most part, I agree. View names for homework assignments and challenges isn't the most important topic to bother yourself with. However, I encourage junior developers on my team to always be ready to defend function, variable, and view names. When we discuss cooking on a grill, we don't use code names, or generic descriptions.
We say chicken, steak, or chops! We use specific names for seasonings and rubs. Use natural language, and your team will understand your approach and intentions. It's not technically necessary, but it's a good habit to embrace. |
|
@Obelix, re: formatting of currency Thank you for your pointer. I found that currency formatting is to a large extent governed by locale. In my simulator the locale was set to "en_US". While setting the currency code to "EUR" did fix the currency symbol problem, it did nothing to fix the formatting of the number in terms of thousands and decimal separators. Once I set the language in the simulator to "Nederlands" (i.e., Dutch), and the region to "Netherlands", all was properly (for me) formatted. I had a look into achieving this programmatically, and I came up with the following. Instead of using On the global level a declaration:
An
A different line to display the amount in
and a different line to show it in
That is all. While working on this I found that |
|
Nice! Thanks for posting your solution, it's a tricky topic and your answer will certainly help others in the future! Enjoyed testing the coding tips you posted. Helped clarify the solution. All this talk about spending Euros in the Nederlands has made think back fondly on the few bottles of Westvleteren I enjoyed on my trip! |
|
This thread was really helpful. I just finished this challenge too, thanks to you both. I used an enum I defined with String raw values for expense |
|
i completed it in an elegant way, here is the main code
|
|
Thank for the ideas and pointers to getting these tasks done. Took the adivise to consolidate data and methods to an "Expense" Class, which was a bit of a challenge. Class:
Then found this chunk of code that creates the sections, leveraging an enum for Types
|
|
Here is my approch:
|
SAVE 50% To celebrate WWDC23, all our books and bundles are half price, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.
You need to create an account or log in to reply.
All interactions here are governed by our code of conduct.
Link copied to your pasteboard.