Just in case you wondered how NSLocalizedString is called in Swift. It is the same, but needs a “comment:” label, because the other arguments in between are optional.
For Example:
let text = NSLocalizedString(“Your Text”, comment:” Your comment” )
Making the world a better place, one small app at a time
App Programming Tips from programmer to programmer
Just in case you wondered how NSLocalizedString is called in Swift. It is the same, but needs a “comment:” label, because the other arguments in between are optional.
For Example:
let text = NSLocalizedString(“Your Text”, comment:” Your comment” )
Wenn einen der Schülerpraktikant fragt: “Gibt es in Swift auch so etwas wie statische Klassen wie in Java?”, dann weiss man, …
– Hier hat jemand etwas schon ziemlich gut verstanden
– Es könnte sein, dass dieser Schüler mal ein Programmierer wird
– Solche Sätze sind der Grund, warum wir uns mit Schülerpraktikanten belasten. Und warum wir stolz darauf sind, das zu machen. Und warum es auch manchmal Spaß macht.
Übrigens: Wer nicht versteht, was gemeint ist – egal. Ich glaube man kann auch als Nicht-Programmierer ahnen, dass das ein ziemlicher Fach-Satz von einem Jugendlichen ist.
Und zuletzt die Auflösung der Frage: Ja, die gibt es, sie heissen in Swift “Type Methods”, werden func class mymethod() geschrieben und myclass.mymethod() aufgerufen.
From time to time we have pupil interns. Our last intern, let’s call him John started some Xcode Swift programming and all was fun and great. After more than a week of successful programming small pieces of this and that he created a png picture file using the gimp editor. He then pulled the file into the project and from that minute on, Xcode did not want to compile any more.
It turned out, that the problem was the copypng perl script used by Xcode (found here: Programme ▸ Xcode.app ▸ Contents ▸ Developer ▸ Platforms ▸ iPhoneOS.platform ▸ Developer ▸ usr ▸ bin). Since the intern had created a subdirectory called John`s programs, he had a directory name with not only a space, but also a capital letter and a quote in it (I can not guarantee the particular type of quote any more, but I think it was the one I used above).
When I think back of the times where just on of the three was forbidden or problematic, I still shiver and I have to admit, that I am still a little bit superstitious regarding the use of blanks in directory names, even nowadays.
It turned out, that while compiling the swift files with that quote char in the file name did work, it did not work for the copypng perl script.
We changed the directory name and all went well a second later.
Filed a radr (bug report), Number 19653543
When we decided to add core data to a swift project, we thought, a simple drag and drop of the core data model file would do the job. After some time wondering why it did not work, we finally found out, that xcode did not compile the file correctly, creating only a mom-file and not the momd-file package. The fix was easy, of course. We only had to create a new core data model file using New->File->… and then to copy the content from the old to the new model, which then worked as expected.
The other surprise of that day came while trying to access the class that we had created using Editor->Create NSManagedObject Subclass. We could not correctly use the subclass as we had done it using Objective-C. Again, after some minutes I remembered, what I had read in the iBook “Using Swift with Cocoa and Objective-C”, that since Swift has no flat class model, we needed to include the class name into the Class-Field of our Entity.
We did that by selecting the entity, opened the model entity inspector and prefixed our entity class with the project name separated by a dot. I just wonder if that class name ( e.g. project.entity ) would still be accessible using Objective-C as well. May be I’ll try that next time.
When sitting in a cafe with two other smartphone users, we spoke about “kids-safe” restricted mode in the different smartphone systems and how they differ from the restrictions mode in the iPhone. In order to demo (and try it out), I did set my iPhone in the restrictions mode “on” and we analyzed and nodded about nearly all the features.
What surprised my, was, that my self-programmed apps where still there – obviously you have to load them from the app store or my apps where missing some information that app store apps have e.g. like age restrictions.
Then it was time to set the settings back to normal and there came the shocking moment: All Icons were in disorder, they had left their groups, the sorting in the home-screen pages on the iphone were a mess.
I wondered, what would have happened, if I would have had so much icons that the sheer number would not fit on the screen, because I had them all grouped? If you know, feel free to comment.
Of course, I could have made a backup, or re-loaded a previous backup, but unfortunately, I did not know about this hazard and I already had made changes after my last backup a day ago.
So my learning from this experiment: Kids restrictions settings are not for temporary use. If you want to hand over an iPhone to a kid, put it in restricted mode only, if you can live with the disorder afterwards or if you had over the iPhone for a longer time. Or make a backup before handing over.
When I recently did some programming while riding in the commute train, I added an new image view, added an outlet using the Assistant editor of Xcode 5 and started to test my program. All worked well, I added a few changes and had to hop off the train.
Some hours later I continued testing and was surprised to see a black window instead of my app. I could not remember what I had changed last time. Could it be, that I had made mistakes in the connection of the scenes? Did not look like so. Did I make a mistake in the code? No evidence for that.
Then I finally saw it: Instead of putting the button to hidden, I had put my image view to hidden. I had connected the whole view, instead of connecting the button only – without noticing it. This meant, I had set the view that was meant to be the background to hidden and thus I had a black view into the endless dark black hole of the background behind the background.
When moving one of my projects to iOS 7, I had a strange effect: In this App, I needed a button, that had to change its size. In iOS 6 and Xcode 4.6.3 I had created a button in the interface editor and I could now change its size and always adjust its center as well. In iOS7, this was not possible, obviously because xcode or the run time system always generated a new constraint on how to lay out the button – although I had not given it any constraints. The default was obviously to always get the default constraints.
I experimented a little and came to no better conclusion than to do the button dynamically in the code. Worked perfectly and was possible with little effort as well. Seems, I still have to get used to the constraints system.
I was working on a project for quite a while, so the storyboard of that project was filled with 19 screen controllers. When the project moved from iOS 6 to iOS 7, we had some issues with autolayout, but we thought we had them all wiped out.
Then one day entering the storyboard in Xcode crashed Xcode V5.0.2. Of course I could have checked in version control which of the last versions would open without problems, but I went down another path.
I had saved the last versions of xcode (v5.0 and v4.6.2) and tried to open the storyboard with version 5.0, which worked. And since the message in the crash contained the word „cell“, I searched for cells by entering cell in the document outline view search bar (the list of all views and view controllers that you can view on the left hand of the storyboard itself).
While the first three table view cells where all OK, the fourth table view cell was in a table view with size zero (0) for height and width. Needless to say, that putting the sizes to zero had been Xcode’s idea, not ours. That zero size was probably the reason, I assumed, so I changed the size of the parent table view to something bigger than two times zero. And yes, this time Xcode 5.0.2. opened the storyboard file without problems.
Here is the error lines I had in my console output and in the crash report (for reference):
Details: Failed to compute auto layout status IBUILabel, IBUITableViewCell, and IBUITableViewCellContentView.
Reason: Any table view cell being added to a layout engine should be contained in a table view in order to get the correct metrics
Todays Surprise using NSMutableArray
I am programming in Objective-C for 4+ years now. And don’t get me counting, how many years have passed, since I programmed my first program in school. After that amount of time, surprises in programming are not that common any more for me. After so many years, you develop a gut feeling, what is safe programming and what is possibly not a good idea.
Today, I was reminded again, that it is a good idea to listen to your gut feeling. I was combining a loop through a collection of items together with an act of deleting one of the items. When I was programming it, my gut feeling told me, wait – this could be confusing for the array management (class) software. May be, it has a reference to an item and I am deleting it and this confuses everything.
So I checked the description of the class. I could not find any comments regarding that and went on.
A few days later however, after I had programmed it, I learned, that I had not looked up the documentation good enough. Somewhere in the documentation I found the hint: Deleting an element while enumerating it (running in a loop through all elements of that array) is potentially unsafe. The same applies to adding elements or replacing elements. So I needed to change my implementation.
I didn’t know what to feel. Should I be proud, because I had “felt it”? Should I feel stupid, programming it that way? Should I be upset, because it sure is possible (for Apple) to implement the array thing without these problems. But when programming, you have to make tradeoffs. This way, the more general case is surely faster.
So how did I do it? I changed my code to first collect all elements, that need to be deleted, in a second array and then, after the enumeration loop has finished, delete them all at once.
The alternative implementation is a good idea as well: Make a copy of the collection, enumerate through the copy and modify the original.
Some time ago I was trying to remember a method name that I wanted to call in order to achieve the desired effect. Usually the Xcode app is able to list all the possible methods, but I had some errors in the file, so Xcode was confused and I could not fix all of it at the same time. So I decided, that I should implement a method, that lists all possible methods of a given class.
This is relatively easy in Objective-C, since the method names are inside every program, because the name resolution is done at runtime in Objective-C. All I had to do was implement some code fragment like this:
#import <objc/runtime.h>
...
Class elem = [objectToBeListed class];
while (elem) {
NSLog(@"%s", class_getName( elem ));
unsigned int numMethods = 0;
Method *mList = class_copyMethodList(elem, &numMethods);
if (mList) {
for (int j=0; j < numMethods; j++) {
NSLog(@" %s",
sel_getName(method_getName(mList[j])));
}
free(mList);
}
if (elem == [NSObject class]) {
break;
}
elem = class_getSuperclass(elem);
}
This gives a fairly long listing of all methods of your class and all its super classes.
And it also revealed some humor from the Apple guys, when I listed a UIViewController Class. Because in the listing there I found the following class name (broken in to smaller pieces for better readability):
attentionClassDumpUser:yesItsUsAgain:
althoughSwizzlingAndOverridingPrivateMethodsIsFun:
itWasntMuchFunWhenYourAppStoppedWorking:
pleaseRefrainFromDoingSoInTheFutureOkayThanksBye:
If you find that hard to read, here is the readable version of that “sentence”:
attention Class Dump User: yes Its Us Again: although Swizzling And Overriding Private Methods Is Fun: it Wasnt Much Fun When Your App Stopped Working: please Refrain From Doing So In The Future Okay Thanks Bye:
To swizzle is computer-speak for changing something, for “messing around”. Although I had not planned to swizzle with any pointer or to override any method, I did feel like this sentence was directed to people like me, dumping the list of methods.
Of course, the documentation does not list this function. And there is no such function in Mac OS X, so this is an iPhone “feature”.