Thursday, March 16, 2017

Inherited uiviewcontrollers references in one storyboard. This class is not key value coding-compliant for the key ...

I often inherit my UIViewControllers to add functionality on top of already existing. All works fine, but today I ran into the weird problem. Setup like this:



Where rangeItemEditor view controller inherits from itemEditor view controller. All outlets connected in the parent view controller. On row tap I do performSegue and then this:

This class is not key value coding-compliant for the key ...

Complaining about one of the outlets. After standard troubleshooting, checking that .destinationViewController is right, bunging my head a bit against the wall and trying [navigationController push] which worked I looked more carefully at the Storyboard ID values for these references. Here is obviously a good one:



And the other one, inherited rangeItemEditor had it empty. Filling it in and running again proved the idea that missing Storyboard ID in Identity tab for a references storyboard is a bad thing. I was not clearing this out though, not sure how it happened to be empty.

Thought I'd share to make your troubleshooting of similar cases faster!

In the end I got rid of these references in the storyboard and used [navigationController push]. Why? I just really don't want these crashes when xcode UI Editor decides to remove something behind the scenes. I've witnessed this "open the file -> get the mess" already in xcode storyboards and I really better stay safer here with using old gold manual push. Staying away from the magic until it has predictable results :).

Monday, February 20, 2017

Working around WITH not being available in older versions of sqlite.

For one of my iPhone apps I need to rename route points to match their order as they are inserted or deleted, I started with an easy WITH version:


[NSString stringWithFormat:@"WITH wcte (id, wname) AS (SELECT w.id, '%@ ' ||  (SELECT COUNT(*) + 1 FROM waypoint WHERE vY1 < w.vY1) as wname FROM waypoint w)  UPDATE waypoint SET \"name\" = (SELECT wname FROM wcte WHERE id = waypoint.id) WHERE \"name\" LIKE '%@ %%' OR \"name\" is null OR \"name\" = ''", LSSTRING(@"Point"), LSSTRING(@"Point")]

And ran into the problem when testing on iOS8.1, obviously its version of sqlite didn't support WITH at that time.

So here is the workaround solution for older sqlite versions:

[NSString stringWithFormat:@"UPDATE waypoint SET \"name\" = (SELECT '%@ ' || (SELECT COUNT(*) + 1 FROM waypoint w WHERE w.vY1 < w1.vY1) FROM waypoint w1 WHERE w1.id = waypoint.id) WHERE \"name\" LIKE '%@ %%' OR \"name\" is null OR \"name\" = ''", LSSTRING(@"Point"), LSSTRING(@"Point")]

Not that nicely looking, but I'm still committed to support iOS8 for a few more months. If you are puzzled by that LSSTRING part - that's just my macro for the LocalizableString as I only want to rename these points that are named automatically and surely I want to name them in the localized manner. Punto it is in Spanish (I hope) :). vY1 is a cryptic name for the order column :).

Would not be publishing at all, but sqlite syntax sometime is surprising in what it can or can't do, so I thought I might save time to someone.

If you are into hiking, fishing, cycling or classic skiing here is the app link, it's free: https://itunes.apple.com/us/app/id1120906807


Friday, December 9, 2016

Elixir, Phoenix, React, Redux and ES6 - I'm a complete beginner again.

I started with Erlang and now progressing with Elixir, Phoenix, React, Redux and ES6 stack. Was feeling a bit lost when seeing stuff like this:

 var createStoreWithMiddleware = (0, _redux.applyMiddleware)(reduxRouterMiddleware, _reduxThunk2.default, loggerMiddleware)(_redux.createStore);

or:

const store = autoRehydrate()(createF8Store)(reducers);

Had to remind myself on a simple function chaining, like:

const p = (store)=>{console.log("I'm an almighty container, you passed me the store: " + store);};

const f = (a,b)=>{
  console.log("Thanks for a and b: " + a + ", " + b + " it helped me to build a container with I return to you. Pass a store into it!");
return p;
};

f(3,4)("Store is just a name 'John'");

With the output of:


  • "Thanks for a and b: 3, 4 it helped me to build a container with I return to you. Pass a store into it!"

  • "I'm an almighty container, you passed me the state: Store is just a name 'John'"
Beginner mind work play games with me, tendency to get lost on trivial subjects is quite high :):):).

A list of resources I really appreciated so far:

React:
https://facebook.github.io/react/docs
https://egghead.io/courses/react-fundamentals
https://egghead.io/courses/react-flux-architecture-es6

Redux:
http://redux.js.org
https://egghead.io/lessons/javascript-redux-reducer-composition-with-combinereducers

ES6:
https://ponyfoo.com/articles/es6

ES6 and modules (oh, how could have I got so much behind?):
https://24ways.org/2014/javascript-modules-the-es6-way/
https://babeljs.io/learn-es2015/

ES6 Promises: http://www.datchley.name/es6-promises/

I also found this article being an awesome walkthrough on getting React/Redux/ES6 and more together in Facebook's makeitopen app:
http://makeitopen.com/tutorials/building-the-f8-app

Webpack:
http://ryanchristiani.com/introduction-to-webpack/

Elixir and Phoenix: 
Pragmatic programmers - Elixir programming, Phoenix programming.
Phoenix and Trello clone: http://codeloveandboards.com/blog/2016/01/14/trello-tribute-with-phoenix-and-react-pt-1/



Wednesday, June 15, 2016

Me, a troll! My recent MS experience :)

If I had to show one example for all for my recent Microsoft experience as a developer and user, here it is. The welcome page in VS 2015 opening the xml feed when you click on "More news":

I will not be telling here how I'm trying to keep my ASUS tablet in sync with time after upgrading to Windows 10. The above is enough declaration of "we are not for humans" and "we don't really care" :). 

This is me, a troll in the MS land. I used to be a regular guy here. Sorry. I'm working hard on my escape plan now.

Stan.

P.S. To my problem with Windows 10 time. Given how different apps in windows fail differently based on that time sync problem and learning Erlang at the moment, it was quite up to point to read about Erlang time here: http://learnyousomeerlang.com/time, wishing you a good read! :).

Thursday, May 26, 2016

Symbolicating bitcode crash logs in XCode

As of Xcode version 7.3 there is still a problem with symbolicating the bitcode crash logs. I've attempted several solutions, here and here, but here is what I came to:

1. Crash logs provided are for the dSYMs that Apple also provides. Just go to the iTunes connect and download them:



Once you have them right click on the crash in xcode -> "Show in finder" and copy to some target directory - that's actually a crashpoint file you are going to get.

My target directory is now ~\Desktop\crashes and here is how it looks:



Where #1 are dSYMs as copied from the iTunes connect. #2 is the crashpoint saved from the crash organizer window in xCode. #4 is a crash log extracted from the crashpoint file (right click and "show package contents")

To get #3 - a symbolicatecrash app, execute this in the target directory (xcode 7.3):


cp /Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash symbolicatecrash

For different versions of xcode the location of symbolicatecrash will be different.

To get symbolicatecrash ready to operate execute:

export DEVELOPER_DIR='/Applications/Xcode.app/Contents/Developer'

Only one step is left! That's to get your crash log symbolicated:

./symbolicatecrash a.crash dSYMs/ > a.log

And the output file a.log is looking like:



Way better, is not it?

There are nuances that I would not touch here, like these dSYM files you downloaded are for different architectures and it would be the best to match your specific crash log to a corresponding dSYM. I'll leave this detail to you, my experience is that function names do match quite well, then it is just about the line of code information you'll be getting. In above picture, given crash and dSYM are matched well, you can see the line of code where the crash exactly happened. Otherwise you'd see +xyz there and that's not that helpful.

This is it. Please don't judge me strictly, I'm not an expert in any field, as I learnt over time :)! Knowing more than I do? Share your knowledge in the comments!

Yours,
Stan.

Wednesday, April 27, 2016

Erlang http response emulator

Recently I had to implement a "transparent" proxy between Tibco and Blackberry. I thought I'd share the erlang module I wrote to emulate responses from BB as you can't really expect from BB server to give you error responses or timeouts so you can test your proxy part. Here it is:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
-module(httpemulator).
-author("stanislavdvoychenko").

-export([client/0, server/0,start/0,accept/1,enter_loop/1,loop/1]).

client() ->
  {ok, Socket} =  gen_tcp:connect("localhost", 4001,[list, {packet, 0}]),
  ok = gen_tcp:send(Socket, "packet"),
  receive
    {tcp,Socket,String} ->
      io:format("Client received = ~p~n",[String]),
      io:format("Client result = ~p~n",[String]),
      gen_tcp:close(Socket)
  after 1000 ->
    exit
  end.

server() ->
  Pid = spawn(fun()-> start() end),
  Pid.

start() ->
  io:format("Started Server:~n"),
  {ok, Socket} = gen_tcp:listen(4001, [binary, {packet, 0},{reuseaddr, true},{active, false}]),
  accept(Socket).

accept(ListenSocket) ->
  io:format("Accept Server:~n"),
  case gen_tcp:accept(ListenSocket) of
    {ok, Socket} ->
      Pid = spawn(fun() ->
        io:format("Connection accepted ~n", []),
        enter_loop(Socket)
                  end),
      io:format("Pid ~p~n",[Pid]),
      gen_tcp:controlling_process(Socket, Pid),
      Pid ! ack,
      accept(ListenSocket);
    Error ->
      exit(Error)
  end.

enter_loop(Socket) ->
  %% make sure to acknowledge owner rights transmission finished
  receive ack -> ok end,
  loop(Socket).

loop(Socket) ->
  io:format("Loop Server:~n"),
  case gen_tcp:recv(Socket, 0) of
    {ok, Data} ->
          io:format("Server got data = ~s~n", [Data]),
          Match = re:run(Data, ".*Emulator-Command:\s(.+)\r", [{capture, [1],list}]),
      case Match of
        {match, ["timeout"]} -> Response = timeout("timeout");
        {match, ["protocolviolation"]} -> Response = protocol_violation("Omitting carriage return, this should cause the protocol violation");
        {match, ["httperror"]} -> Response = http_error("500", "Internal Server Error");
        _ -> Response = response("testing")
      end,

io:format("Match: ~p~n", [Match]),
          gen_tcp:send(Socket, Response);
          %%loop(Socket);
    {error, Reason} ->
      io:format("Error on socket ~p reason: ~p~n", [Socket, Reason]),
      gen_tcp:close(Socket)
  end.

response(Str) ->
  B = iolist_to_binary(Str),
  iolist_to_binary(
    io_lib:fwrite(
      "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nContent-Length: ~p\r\n\r\n~s",
      [size(B), B])).

timeout(Str) ->
  timer:sleep(1000000000),
  B = iolist_to_binary(Str),
  iolist_to_binary(
    io_lib:fwrite(
      "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nContent-Length: ~p\r\n\r\n~s",
      [size(B), B])).

protocol_violation(Str) ->
  B = iolist_to_binary(Str),
  iolist_to_binary(
    io_lib:fwrite(
      "HTTP/1.0 200 OK\nContent-Type: text/html\nContent-Length: ~p\n\n~s",
      [size(B), B])).

http_error(Code, Str) ->
  B = iolist_to_binary(Str),
  iolist_to_binary(
    io_lib:fwrite(
      "HTTP/1.0 ~s ~s\r\nContent-Type: text/html\r\nContent-Length: ~p\r\n\r\n~s",
      [Code, B, size(B), B])).

This Erlang module expects you to sent an extra http header Emulator-Command: * where * can be:

httperror -> returns 500 and Internal Server Error
timeout -> runs a long sleep on Erlang side, causes timeout on a proxy side
protocolviolation -> As I built the proxy in ,net WCF it was funny to see that MS takes only \n in the http headers as a protocol violation, so \r\n is required to keep MS happy.

anything else there or omitting this header will just return proper http response with "testing" body.

Disclaimer. I'm only starting to learn Erlang so please take the code with caution of course!

To compile in the erlang shell:

c(httpemulator).

To start emulator server:

httpemulator:server().

To end the emulator process:

exit(pid(0,96,0), old).

Pid is returned at the server start.

Hope it can be useful :).

Thursday, April 14, 2016

xcode - Configure for analyzing. The scheme is not configured for analyzing.

I'm used to run analyzing cycle on my apps when moving closer to their public release. This time xcode (7.3 (7D175)) greeted me with:


"Edit the scheme to enable analyzing, or cancel the action." with that "Edit Scheme ..." was not opening anything and I didn't notice anything extra in the schema editor to enable analyzing.

I even created a clean new project to see if error would be present there as well, and it was.

So after scratching my head a bit I just set a RUN_CLANG_STATIC_ANALYZER as true for the target/build where I needed it:


This way I got the static analysis messages back.

Hope this can help someone!

Update. Or as Jaime Santana commented, just "launch Analysis from the menu option Menu -> Product -> Analyze". Thank you Jamie, that worked!