Archive for the ‘Swift Coding’ Category

More Problems with Object Designs

Wednesday, April 3rd, 2019

xcode.jpg

This morning I was playing around with the CryptoQuip solver, and realizing that the mapping code I had could be made a little simpler if I used the fact that ASCII character representations are all numerically ascending, and that makes character math something to use - as opposed to simple look-ups. For instance, if we look at the existing code for +createPatternText::

  1. + (NSString*) createPatternText:(NSString*)text
  2. {
  3. const char *src = [[text lowercaseString] UTF8String];
  4. NSUInteger len = [text length];
  5. const char *ascii = "abcdefghijklmnopqrstuvwxyz";
  6. char pattern[255];
  7. for (NSUInteger i = 0; i < len; ++i) {
  8. pattern[i] = ascii[strchr(src, src[i]) - src];
  9. }
  10. pattern[len] = '\0';
  11. return [NSString stringWithUTF8String:pattern];
  12. }

the look-up on line 8, using the const char array defined on line 5, is really just an offset calculation, and can be replaced with:

  1. + (NSString*) createPatternText:(NSString*)text
  2. {
  3. const char *src = [[text lowercaseString] UTF8String];
  4. NSUInteger len = MIN([text length], 255);
  5. char pattern[255];
  6. for (NSUInteger i = 0; i < len; ++i) {
  7. pattern[i] = 'a' + (strchr(src, src[i]) - src);
  8. }
  9. pattern[len] = '\0';
  10. return [NSString stringWithUTF8String:pattern];
  11. }

and the result is exactly the same. But now, we're not creating the const char array on the stack, on each call, and the offset into the array is the same addition as we are doing here. Simpler.

But when we go to Swift, we see that the beauty and elegance of the underlying data is being clouded with the all-too-common object oriented design of Character.

  1. var pattern: String {
  2. get {
  3. let ascii: [Character] = ["a","b","c","d","e","f","g","h","i","j","k",
  4. "l","m","n","o","p","q","r","s","t","u","v",
  5. "w","x","y","z"]
  6. var ans = ""
  7. let src = Array(self.lowercased().utf8)
  8. for c in src {
  9. ans.append(ascii[src.firstIndex(of: c)!])
  10. }
  11. return ans
  12. }
  13. }

Sadly, we can't simplify line 9 because the Character object doesn't allow for construction based on an ASCII value. Sure, it has all kinds of nice interrogation methods to test and see if it's ASCII, or uppercase, or a number... but you can't actually do the simple math of adding 1 to 'a' and getting 'b'. That is a shame, and it's not something you can easily add because the Character class would need a new -init: method.

So while I really like parts of Swift 5, I think they didn't really think about all the uses that ObjC fits into when making the new classes. It's a process, I get that, but it's causing folks to write code around these issues, and that's a mistake. No one will go back and fix their code when, and if, they add a way to do this.

Updating my WordPress CodeHighlighterPlus to GeSHi 1.0.9.0

Thursday, March 28th, 2019

wordpress.gif

This morning I decided to see if I couldn't fix the Swift highlighting on this blog by updating to the latest GeSHi 1.0.9.0 - which is now using PHP 7, and as it turns out, so is HostMonster, so I'm in luck! 🙂 At the same time, I really wanted to document all the components and links so that this post makes it a lot easier to update things later.

As a point of reference, the CodeHighlighterPlus project is based off the CodeHighlighter WordPress plugin, and it's not bad - it's just not been updated in many years, and there are a lot of added languages in that time. Still... I tip my hat to the original authors, as I couldn't have done it without them.

The steps to do this required a little digging, but that wasn't bad - in that I had a few posts about this process already, and so let's just repeat them here to make sure it's all clear for the next time. I started by making sure that my local CodeHighlighterPlus plugin was up-to-date with the GitHub repo. All good, so let's get the latest code from GeSHi, and just overlay it on the local repo. Replace where necessary, and then we're up to date with GeSHi... but it's not really cleaned up the way I like it.

The next thing was to update the geshi.php file for a few changes. The first thing I wanted to tackle with CodeHighlighterPlus was the line numbers. There was far too much space between the lines in a code sample with line numbers. This is corrected simply in the style for the lines:

  1. /**
  2.   * Line number styles
  3.   * @var string
  4.   */
  5. protected $line_style1 = 'font-weight: normal; vertical-align:top;';
  6.  
  7. /**
  8.   * Line number styles for fancy lines
  9.   * @var string
  10.   */
  11. protected $line_style2 = 'font-weight: bold; vertical-align:top;';

to:

  1. /**
  2.   * Line number styles
  3.   * @var string
  4.   */
  5. protected $line_style1 = 'margin: 0; font-weight: normal; vertical-align:top;';
  6.  
  7. /**
  8.   * Line number styles for fancy lines
  9.   * @var string
  10.   */
  11. protected $line_style2 = 'margin: 0; font-weight: bold; vertical-align:top;';

The last change is for the blank lines that start, and end, the code section when you use line numbers. It's just plain annoying. Change:

  1. // Get code into lines
  2. /** NOTE: memorypeak #2 */
  3. $code = explode("\n", $parsed_code);
  4. $parsed_code = $this->header();

to:

  1. // Get code into lines
  2. /** NOTE: memorypeak #2 */
  3. $code = explode("\n", $parsed_code);
  4. // remove a blank first and last line
  5. if ('' == trim($code[count($code) - 1])) {
  6. unset($code[count($code) - 1]);
  7. $code = array_values($code);
  8. }
  9. if ('' == trim($code[0])) {
  10. unset($code[0]);
  11. $code = array_values($code);
  12. }
  13. $parsed_code = $this->header();

and we are good to go with the changes to the code. Check everything in, push it up to GitHub and we're ready to deploy it.

At this point, I just need to deploy this to each of the WordPress sites on my server - and that's as simple as:

  $ cd public_html/blog/wp-content/plugins/CodeHighlighterPlus
  $ git pull

where blog is the directory in the WordPress content for the specific blog I'm working with. I simply use GitHub as the mechanism of deployment - with a pull system to make sure it doesn't mess too much stuff up.

In this release of GeSHi, we now have support for the following languages:

4cs            e              magiksf        qml
6502acme       ecmascript     make           racket
6502kickass    eiffel         mapbasic       rails
6502tasm       email          mathematica    rbs
68000devpac    epc            matlab         rebol
abap           erlang         mercury        reg
actionscript   euphoria       metapost       rexx
actionscript3  ezt            mirc           robots
ada            f1             mk-61          rpmspec
aimms          falcon         mmix           rsplus
algol68        fo             modula2        ruby
apache         fortran        modula3        rust
applescript    freebasic      mpasm          sas
apt_sources    freeswitch     mxml           sass
arm            fsharp         mysql          scala
asm            gambas         nagios         scheme
asp            gdb            netrexx        scilab
asymptote      genero         newlisp        scl
autoconf       genie          nginx          sdlbasic
autohotkey     gettext        nimrod         smalltalk
autoit         glsl           nsis           smarty
avisynth       gml            oberon2        spark
awk            gnuplot        objc           sparql
bascomavr      go             objeck         sql
bash           groovy         ocaml-brief    standardml
basic4gl       gwbasic        ocaml          stonescript
batch          haskell        octave         swift
bf             haxe           oobas          systemverilog
biblatex       hicest         oorexx         tcl
bibtex         hq9plus        oracle11       tclegg
blitzbasic     html4strict    oracle8        teraterm
bnf            html5          oxygene        texgraph
boo            icon           oz             text
c              idl            parasail       thinbasic
c_loadrunner   ini            parigp         tsql
c_mac          inno           pascal         twig
c_winapi       intercal       pcre           typoscript
caddcl         io             per            unicon
cadlisp        ispfpanel      perl           upc
ceylon         j              perl6          urbi
cfdg           java           pf             uscript
cfm            java5          phix           vala
chaiscript     javascript     php-brief      vb
chapel         jcl            php            vbnet
cil            jquery         pic16          vbscript
clojure        julia          pike           vedit
cmake          julia.bak      pixelbender    verilog
cobol          kixtart        pli            vhdl
coffeescript   klonec         plsql          vim
cpp-qt         klonecpp       postgresql     visualfoxpro
cpp-winapi     kotlin         postscript     visualprolog
cpp            latex          povray         whitespace
csharp         lb             powerbuilder   whois
css            ldif           powershell     winbatch
cuesheet       lisp           proftpd        xbasic
d              llvm           progress       xml
dart           locobasic      prolog         xojo
dcl            logtalk        properties     xorg_conf
dcpu16         lolcode        providex       xpp
dcs            lotusformulas  purebasic      xyscript
delphi         lotusscript    pycon          yaml
diff           lscript        pys60          z80
div            lsl2           python         zxbasic
dos            lua            q
dot            m68k           qbasic

And with the addition of Swift, I have highlighting on all the code snippets I've been adding. Very nice!

Xcode 10.2 is Out

Tuesday, March 26th, 2019

xcode.jpg

This morning, after I updated to macOS 10.14.4, I noticed that Xcode 10.2 was out with Swift 5, and that has the new Strings, and the ABI compatibility, and a host of new things. So let's get that going, and see how it changes things. I really haven't read what is new in Swift 5 - other than the new Strings, so that will be something to read up on this morning.

What I've found in converting an ObjC project is that a few of the localizations needed to be cleaned up - Xcode did that just fine, and then it built and ran just fine. But for the Swift project, it complained about the use of index(of:) and suggested that it be changed to firstIndex(of:) - which is fine, but I don't know that anyone used to coding for very long makes that mistake - but OK... I get it.

The next one said that in this code:

  ans.append(ascii[self.index(of: c)!.encodedOffset])

needed to be changed to:

  ans.append(ascii[self.firstIndex(of: c)!.utf16Offset(in: self)])

and figuring that out took some time.

Specifically, they deprecated the encodedOffset - which they say was being misused. And then didn't really give me a replacement. I had to fiddle and search the docs for what to put in it's place. And given that this is coming off a call to self - how is it that utf16Offset() doesn't default to that?

In any case, I got that fixed, and then I refactored the code for pattern from:

  let ascii: [Character] = ["a","b","c","d","e","f","g","h","i","j","k",
                            "l","m","n","o","p","q","r","s","t","u","v",
                            "w","x","y","z"]
  var ans = ""
  for c in self {
    ans.append(ascii[self.firstIndex(of: c)!.utf16Offset(in: self)])
  }
  return ans

to:

  let ascii: [Character] = ["a","b","c","d","e","f","g","h","i","j","k",
                            "l","m","n","o","p","q","r","s","t","u","v",
                            "w","x","y","z"]
  var ans = ""
  let src = Array(self.utf8)
  for c in src {
    ans.append(ascii[src.firstIndex(of: c)!])
  }
  return ans

I just didn't like the way the encoding was being handled, and that got to be a real annoyance... so by just converting it to UTF8, and then using that array for indexing, I was able to do the same thing - and it looks a lot cleaner.

I'm less and less a fan of the speed with which they released Swift. I understand they needed to get it out in the wild, and they had to answer requests for features, but they added too many too quickly, and without the long-term consideration that they are usually known for. I mean look at ObjC... the classes changed a little, but the language was shipping product for 5 yrs, and Swift has been around for 5 yrs, and it's still not close to stable.

Part of it is also that they stuck with OOA&D, and that's got to be a killer.

Reading Up on CloudKit

Wednesday, September 26th, 2018

CloudKit

After I went through Swift and Xcode, I was looking for something to read, and CloudKit seemed like a really good thing to read - as I know a friend is using it for his app, and it's one of the really nice features that Apple is making available for server-side uses in the iOS and macOS apps. I'm not at all sure when I'll use it, but I really wanted to get to know it so that I can know what it's capable of, and the basic limitations it's got.

To start, it's important to see this as what might be called a very simple database, and it's probably a good idea to take Apple's cue and call them RecordSets. It really is best to think of them as Collections, as it's not really a traditional database at all, but you can mimic a lot of database activity with it. Still - Collections is the best way to think about it.

Next, they have certainly put in a lot of work to make sure app developers have the tools they need to specify these records on the Apple developer web site. It's really impressive, but then again, Apple uses CloudKit a lot - so it makes sense that you make the tools that help you make apps.

What's interesting is that they have a very logical, clear, data access pattern that covers getting just the updated records... or sending a predicate and getting all the records that match that, or paging them as needed to make the app more responsive to the user. What I find very nice about CloudKit is that for thumbnails of the images - they don't do a thing - it's up to you, the app developer, to make those, and put those in the record. That way, you control the style, image quality, etc. of the thumbnail. Very nice.

I Like that they have the batch and single operation interface, and they have really gone all-in on the NSOperation as the tool for doing all this work. If you get used to that, and good at using it you're going to be set with CloudKit. They have subclassed that to have a lot of different operations, and true to NeXT and Apple form, the names are a little strange to me now - having done a lot of functional coding over the last few years - where names are typically a lot shorter, but that's just the way NeXT has always been.

As I was watching the WWDC sessions, and reading the docs, I realized that this could not really be made a lot simpler for the general case of interacting with iCloud, but it sure was a lot more complicated than any one app would really need. I kept thinking about how to simplify this and make it into a library with simpler access patterns. Then I'd realize that it would be restrictive, and so it would only be good for a subset of all use-cases, and again Apple did the right thing, and it's complex because it's a complex system.

Still... I can bet that if I had to use it in an app, I'd have to make a Framework or something to encapsulate the use cases that I was going to be using - just because I'd need to abstract this away to make it simpler to see how the part interacted with one another. But I suppose that another point to consider is that an app isn't about a lot of complexity, and so interacting with CloudKit is probably the most complex thing an app is doing, and so it's not really surprising that this is as complex as it is.

Low down: it's impressive, and full-featured, and I think it's great that Apple made it.

MacOS 10.14 – Mojave Arrives!

Tuesday, September 25th, 2018

Apple Computers

Yesterday, around noon, I guess, macOS Mojave was released, and signified the end of a very exciting week for Apple. First it was iOS 12, and Xcode 10, then the new iPhones, then macOS Mojave. What a week!

I'm not going to use Dark Mode - it's just too hard for me to read the small text, but that's OK. I like that Apple is trying new things, and it's getting people excited about the UI again, which is always good. I do like a few of the UI changes that they added - there is now a clear distinction between the apps in the Dock, and those that are permanent members of the Dock. Nice. I also like that Safari 12 is getting more strict with the security and ad blocking. It's an entirely different world out there now - as opposed to 10 yrs ago, and I like that Safari, and Apple, feel that security and privacy is a fundamental human right.

There are tons of things under the covers, I'm sure. I've read about several, and as Xcode 10 was likely the build system, I'm guessing that there are nice performance boosts in several spots as well. All very cool stuff.

Xcode 10 Performance Tests

Tuesday, September 18th, 2018

xcode.jpg

This morning, with Xcode 10 updated yesterday with iOS 12, I thought I'd take a run at the Quipper code that is based on Swift 4.2. In the past tests on Xcode 9, I was seeing times in the 40 msec (Release build) and that was nice as it was fully 20 msec faster than ObjC on the same machine, but it's still a far cry from the 6 msec of Clojure on the same machine.

But I've heard a lot about the speed improvements in iOS 12, and it seemed like a smart thing to test the performance on the same code, on the same box - but with Xcode 10. So I did. Wow.

2018-09-18 06:59:04.76 Clearing out all old data for the attack...
2018-09-18 06:59:04.79 List of Possibles:
2018-09-18 06:59:04.79   ... bivteclnbklzn :: 1
2018-09-18 06:59:04.79   ... O :: 2
2018-09-18 06:59:04.79   ... ncc :: 29
2018-09-18 06:59:04.79   ... pt :: 40
2018-09-18 06:59:04.79   ... vzglcddp :: 46
2018-09-18 06:59:04.79   ... ukl :: 589
2018-09-18 06:59:04.79   ... Fict :: 1727
2018-09-18 06:59:04.79   ... lcpji :: 2168
2018-09-18 06:59:04.79 Starting the word block attack...
2018-09-18 06:59:04.79 working on word: 0 [bivteclnbklzn] - 1 possible matches
2018-09-18 06:59:04.80 working on word: 1 [O] - 2 possible matches
2018-09-18 06:59:04.80 working on word: 2 [ncc] - 29 possible matches
2018-09-18 06:59:04.80 working on word: 3 [pt] - 40 possible matches
2018-09-18 06:59:04.80 working on word: 4 [vzglcddp] - 46 possible matches
2018-09-18 06:59:04.80 working on word: 2 [ncc] - 29 possible matches
2018-09-18 06:59:04.80 working on word: 3 [pt] - 40 possible matches
2018-09-18 06:59:04.80 working on word: 4 [vzglcddp] - 46 possible matches
2018-09-18 06:59:04.80 working on word: 5 [ukl] - 589 possible matches
2018-09-18 06:59:04.80 working on word: 6 [Fict] - 1727 possible matches
2018-09-18 06:59:04.80 working on word: 7 [lcpji] - 2168 possible matches
2018-09-18 06:59:04.80 1 Solution(s) took 7.602294921875 msec

I was just shocked - 7.6 msec - that's within reasonable tolerance with the Clojure code - and all that improvement is in the compiler! I have to tip my hat to the Xcode engineers - that's an amazing improvement. I'm guessing that macOS Mojave is going to be quite a treat in a week, as it's been built with these tools. That's something very nice to look forward to.

For now, I'm super happy with the performance of Swift 4.2 - and while I'm not a huge fan of the syntax, it's got the performance that means it's something to take seriously, and use as opposed to Clojure which was problematic on the iOS and macOS apps anyway.

Great News!

iOS 12 Drops Today!

Monday, September 17th, 2018

IPhoneX

We are entering a very exciting week for Apple folks, such as myself. Today it's iOS 12 with the Memoji, automation with Siri, more efficient code to make a lot of things faster on older hardware, and soon - multi-person FaceTime. That last one is interesting to me as it really challenges Google Hangouts and GoToMeeting. They are good products, but this will be in all iPhones, and that's got a really big advantage in market-share.

I also read the comparison of the iPhone Xs Max with the 13" MacBook Pro - and the iPhone was certainly on par with the laptop... it's just crazy how much capability Apple is packing into these phones... I think I need to do a little looking into ARKit and see what it's got. I'm not really sure that I have an augmented reality idea in me, but it might be really nice to see how to do these things. You just never know.

Exciting week!