I'm setting up a new iOS project and wondering if I should use a Localizable.strings file to keep my strings even without planning to add support for other languages.
I've tried using struct to keep my strings before but I am wondering if this is a good practice. Using Localizable.strings will also work well on the library R.swift, another reason why I am struggling to choose a strategy.
There is no "best practice" in this case. There are practices and some may be a bit more appropriate for your case than others.
You are saying that you are not planning to add support for other languages but it seems like you want to be prepared for it if you change your mind. So first thing is to ask yourself what is the actual problem you are looking solution for. I would say the problem is the overhead you get once app is already out and you need to hunt all the strings you have used in your app and wrap them into NSLocalizedString. This usually includes endless testing and you will still in the end most likely forget to localize at least some strings.
You can from beginning start wrapping things into NSLocalizedString which will in the end help you extract all the strings using native tools from your code. The problem then are still Storyboards; not as much extracting strings from storyboard but removing those default texts you have no plan to translate (Like "Name" will actually be some name and should not be translated). So in my experience this is a half solution.
To solve the Storyboard issue there should be a tool (I can't remember which, maybe some other CocoaPod) which enables you to ignore views that should not be translated. So in this case you need to use 2 things; NSLocalizedString and ignoring untranslatable items in IB.
As you already put it nicely you can use R.Swift to get strings directly from your strings file. This is very neat but also extremely distracting as you develop. Doing so you are forcing developer to first enter a text in strings file before he can use it. Personally I hate that. Also this can be a problem with multiple developers being in conflict. Not to mention this hasn't nearly fixed your issue with Storyboards.
Creating a separate structure system to hold all the strings does work pretty nicely. You don't have to hunt down all of the strings in your code and you don't need to jump to strings file (going to another source is much more pleasant when developing since you can navigate to it very easily). You do also preserve a good structure, assuming you maintain it like label.text = Strings.Settings.User.firstNamePlaceholder which helps you to easily find strings you need or are deprecated. You can remove whole screens with great ease. But it still is an overhead for developer plus you still have an issue that now you need to drag all the outlets from storyboard to set the localized strings to them.
Doing this procedure you can in the end choose to use NSLocalizedString directly or to use R.Swift. In fact you can just use nothing and you will still not have much overtime switching to any of the two (again assuming that hunting down those strings in the code takes most of the time).
Personally I would go with nothing at all or go with creating a custom structure system which then uses nothing but just returns raw strings. But this all really depends on what size is your project of, what type of project, how many things are in Storyboards... It also depends on when you expect to have more resources so you either spend more time now and don't bother later or you simply do it simplest now prepare for a lot of work when localization is indeed needed (hopefully when that happens it is one of the "sweet" problems because it means you have tons of users).
Related
I'm doing a project which involves parsing the histories of common lisp repos. I need to parse them into list-of-lists or something like that. Ideally, I'd like to preserve as much of the original source file syntax as possible, in some way. For example, in the case of the text #+sbcl <something>, which I think means "If our current lisp is sbcl, read <something>, otherwise skip it", I'd like to get something like (#+ 'sbcl <something>).
I originally wrote a LALR parser in Python, which sort of worked, but it's not ideal for many reasons. I'm having a lot of difficulty getting correct output, and I have tons of special cases to add.
I figured that what I should really do is is use lisp itself, since it already has a lisp parser built in. If I could just read a file into sexps, I could dump it into something (cl-json would do) for further processing down the line.
Unfortunately, when I attempt to read https://github.com/fukamachi/woo/blob/master/src/woo.lisp, I get the error
There is no package with the name WOO.EV.TCP
which is of course coming from line 80 of that file, since that package is defined in src/ev/tcp.lisp, and we haven't read it.
Basically, is it possible to just read the file into sexps without caring whether the packages are defined or if they contain the relevant symbols? If so, how? I've tried looking at the hyperspec reader documentation, but I don't see anything that sounds relevant.
I'm out of practice with actually writing common lisp, but it seems potentially possible to hack around this by handling the undefined package condition by creating a blank package with that name, and handling the no-symbol-of-that-name-in-package condition by just interning a given symbol. I think. I don't know how to actually do this, I don't know if it would work, I don't know how many special cases would be involved. Offhand, the first condition is called no-such-package, but the second one (at least in sbcl) is called simple-error, so I don't even know how to determine whether this particular simple-error is the no-such-symbol-in-that-package error, let alone how to extract the relevant names from the condition, fix it, and restart. I'd really like to hear from a common lisp expert that this is the right thing to do here before I go down the road of trying to do it this way, because it will involve a lot of learning.
It also occurs to me that I could fix this by just sed-ing the file before reading it. E.g. turning woo.ev.tcp:start-listening-socket into, say, woo.ev.tcp===start-listening-socket. I don't particularly like this solution, and it's not clear that I wouldn't run into tons more ugly special cases, but it might work if there's no better answer.
I am almost sure there is no easy portable way to do this for a number of reasons.
(Just limiting things to the non-existent-package problem for now.)
First of all there is no portable access into the bit of the reader which decides that tokens are going to be symbols and then looks for package markers &c: that just happens according to the rules in 2.3. So you can't easily intervene in this.
Secondly there's not portably enough information in any kind of condition the reader might signal to be able to handle them.
There are several possible ways out of this bit of the problem.
If you felt sufficiently heroic you might be able to teach the reader that all of the token-starting characters are in fact things you control and then write a token-reader that somehow deals with the whole package thing by returning some object which isn't a symbol. But to do that you need to deal with numbers, and if you think that's simple, well, it's not.
If you felt less heroic you could write a more primitive token-reader which just doesn't even try to deal with anything except grabbing all the characters needed and returns some kind of object which wraps a string. This would avoid the whole number problem at the cost of losing a lot of intofmration.
If you don't care about portability, find an implementation, understand how its reader does it, and muck around with it. There are more open source or source-available implementations than I can easily count (perhaps I am not very good at counting) so this is a pretty good approach. It's certainly what I'd do.
But this is only the start of the problems. The CL reader is hairy and, in its standard configuration (the configuration which is used for things like compile-file unless people have arranged otherwise) can run completely arbitrary code at read time, including code which modifies the reader itself, some of which may do so in an implementation-dependent way. And people use this: there's a reason Lisp is called the 'programmable programming language' and it's that people program it.
I've decided to solve this using sed (actually Python's re.sub, but who's counting?) because it'll work for my actual use case, and was easy.
For future readers: The various people saying this is impossible in general are probably right. The other questions posted by #Svante look like good easy ways to solve part of the problem. Other parts of the problem might be solved more elegantly by replacing the reader macros for #., #+, #-, etc with ones which just make a list, which sounds less heroic than the suggestions from #tfb, but I don't have time for that shit.
For my automated tests, everything works fine, except only when it is in English, and this script needs to be able to run for Spanish versions of the same application too. I am not even sure if this is possible, but is there some way of making Ranorex do some sort of translations or some sort?
Currently, validation doesn't work because obviously the text is in a different language, how can I get around this? If it is even possible.
Usually, when testing an application which can be represented in different languages I would suggest using language independent properties in the RanorexPath (for example an automation id if available).
There are similar questions discussed in the Ranorex forum.
http://www.ranorex.com/forum/nls-testing-local-language-testing-t8438.html
http://www.ranorex.com/forum/localized-t3725.html#p15532
I hope that helps.
I have the exact same issue, and in fact, the displayed message/title is sometimes part of what I want to check depending on the chosen language.
What I did:
My different languages are handled through an xml file
the detection of my UI elements may be based on title (but I prefer unique ID when possible, like user1982826 said), in such a
case, I make that title a variable through XSpy.
In a code collection, I created a method that will initialize those
variables depending on the expected language (I'm using xdocument to
parse my xml)
Then, I call that method at the beginning of the recordings needing those variables (don't forget to bind them).
It's not perfect (I need to call that method multiple times for the moment), but ranorex support pointed me that using databinding from supported external source should do the trick. In my case, I should be able to trasnform my xml in a CSV file at the very beginning of my testsuit, and then use databinding on that file with the very same variables I created: data-driven-testing
Don't know if it's helping, it probably depends on how you handle the different languages of your application...
Also you can build your validations around different languages. Basically you'd just set a flag as a global parameter or a parameter that's held in the Program.cs-s Main method.
So if flag is set to "Spanish" it would do the spanish validations and if "English" the same would apply. You'd just have to capsulate the validations correctly in an if/else statements with userCode modules.
I have just been introduced to the LUA language, and I am embarking on my first project. However, the biggest challenge I am facing now is how to implement or make an Undo and Redo.
However, to make issues clear, the project is a Custom Text Editor, and as a result, the Undo/Redo here is required for editing any input text. I have manage to handle issues like Cut,Copy, Clear, Find Word, as well as Changing Font, Text Colour, inserting tables and images among others, and all these were handled in the lua language. Obviously, there are several of the custom text editors, i believe the effort to cater for many will pave the way for future advancements or improvements. But the Undo/Redo actions are tearing me apart, which from my research is even the lack by most of the existing custom text editors.
I have searched several forums where they all seem to give the tip of using an associative kind of table to load the information, and retrieve them from there. Unbelievably, i think some of these sites are just sharing their knowledge acquired from other sites without any technical view point or whatsoever. This is because, most of the suggestions i come across seem to look alike and the same in all aspect. For about tens of sites visited, there is non where a user has tried to post an example, but all i see is the same complain about the majority of lua users. Undoubtedly, this will seem a bit easy to some respected gurus in this forum.
I don't seem to get the true picture of the suggestions.
Can someone provide me with an example?
Undo/redo is a perfect fit for command pattern.
First you need to write some of the text manipulation functionality per se. Just the do part, without worrying about un- or re-. That will be lots of work in itself.
You will then have a bunch of functions to manipulate your document. Things like insertText(), setFont(), insertJpgImage() and such. The trick is that now you need to wrap each of this functions in a so called command object. Each command class must have a method to do() itself, and to undo() itself.
Now that all your text manipulation operations are represented by command objects, you execute each operation (e.g. bold some text) by something like:
boldCommand = setTextPropertyCommand:new(document, selectedArea, textProperties.bold)
boldCommand:do() --actually modify text
table.insert(commandUndoStack, boldCommand) --keep the command for possible undoing later.
When you want to undo the bolding of some text you can then call:
command = table.remove(commandUndoStack)
command:undo()
NB, if your are using some GUI framework binding in Lua, then it might be the case that this framework has its own readymade undo/redo functionality. For example Qt (with qtlua bindings) offers QUndoStack class.
Since every view controller ends with "ViewController" would it be evil to simply abbreviate it as "VC"? I know the Apple Docs say not to abbreviate things and make the names meaningful but isn't this something that's just obvious what it is? I find it lengthy and verbose to type ViewController after every single one. Also, xcode 4 automatically names the nib file the same as the header and class files. Do you remove the "Controller" part of it?
What are your naming conventions and why did you choose to do it that way?
Thanks
If you're using Xcode, you shouldn't have to type the full name every time. Auto-complete handles that for you.
In general, avoiding abbreviation makes your code more readable and easier to maintain. Sure you know what VC means, but someone else 3 years from now might not understand what you were doing.
In this specific case, it may not make tons of sense, but naming conventions are conventions. We follow them in most cases to make our lives (and others) easier in the future.
Always imagine that the person who will eventually maintain your code is a big mean guy with a hair-trigger temper who knows where you live.
Despite what people seem to say Apple has excellent documentation. They have even gone so far as to provide a Coding Guidelines document.
This not only provides some good examples for you to use, but also helps to understand the way name, conventions and abbreviations are used in the Frameworks.
I wonder what sort of things you look for when you start working on an existing, but new to you, system? Let's say that the system is quite big (whatever it means to you).
Some of the things that were identified are:
Where is a particular subroutine or procedure invoked?
What are the arguments, results and predicates of a particular function?
How does the flow of control reach a particular location?
Where is a particular variable set, used or queried?
Where is a particular variable declared?
Where is a particular data object accessed, i.e. created, read, updated or deleted?
What are the inputs and outputs of a particular module?
But if you look for something more specific or any of the above questions is particularly important to you please share it with us :)
I'm particularly interested in something that could be extracted in dynamic analysis/execution.
I like to use a "use case" approach:
First, I ask myself "what's this software's purpose?": I try to identify how users are going to interact with the application;
Once I have some "use case", I try to understand what are the objects that are more involved and how they interact with other objects.
Once I did this, I draw a UML-type diagram that describe what I've just learned for further reference. What happens after depends on the task I've been assigned, i.e. modify the code, document the code etc.
There is the question of what motivation do I have for learning the new system:
Bug fix/minor enhancement - In this case, I may focus solely on that portion of the system that performs a specific function that needs to be altered. This is a way to break down a huge system but also is a way to identify if the issue is something I can fix or if it is something that I have to hand to the off-the-shelf company whose software we are using,e.g. a CRM, CMS, or ERP system can be a customized off-the-shelf system so there are many pieces to it.
Project work - This would be the other case and is where I'd probably try to build myself a view from 30,000 feet or so to know what are the high-level components and which areas of the system does the project impact. An example of this is where I'd join a company and work off of an existing code base but I don't have the luxury of having the small focus like in the previous case. Part of that view is to look for any patterns in the code in terms of naming conventions, project structure, etc. as this may be useful once I start changing some code in the system. I'd probably do some tracing through the system and try to see where are the uglier parts of the code. By uglier I mean those parts that are kludge-like and may have some spaghetti code as this was rushed when first written and is now being reworked heavily.
To my mind another way to view this is the question of whether I'm going to be spending days or weeks wrapping my head around a system like in the second case or should this be a case where it hopefully takes only a few hours, optimistically that is, to get my footing to make the necessary changes.