Thursday, July 2, 2015

[EMiner] Your Envato Sales and Earnings Insights with Notifications for iOS


Yes this is my new app! (can download here if you're seller at Envato) with took 8 months to get it done! whoops! This happen slower than I expected previously Objective-C app which took me around 6 months to learn and release. Let's see my dev log all in one page!

Here's what I learn and use to develop

  1. Swift 1.0, 1.2, 2.0
  2. Swift Protocols
  3. Xcode Auto Layout
  4. Alamofire 
  5. ReactKit
  6. SwiftTask
  7. Parse iOS
  8. Bolts-iOS

And for Backend

  1. Parse Cloud Code
  2. Parse Javascript
  3. Parse Push
  4. Moment.js
  5. Underscore.js

And for Design

  1. Material design
  2. Google Material Color in Swift
  3. Flat shaded design for logo

Finally landing page at http://debokeh.com/

And here's fun part (kidding)


#1 Archive Error

Everything go as a plan, Even I design all this by myself like usual. I've to revise nearly 5 versions! I'm my worst customer! After digging in Swift migration nightmare and fighting with (awkward) Envato API then the day to release is come....and when I try to Archive... TADAAA
Hmm....

ERROR ITMS-90362: "Invalid Info.plist value. The value for the key 'MinimumOSVersion' in bundle EnvatoMiner.app/Frameworks/Alamofire.framework is invalid. The minimum value is 8.0"

ERROR ITMS-90209: "Invalid Segment Alignment. The app binary at 'EnvatoMiner.app/Frameworks/Alamofire.framework/Alamofire' does not have proper segment alignment. Try rebuilding the app with the latest Xcode version."

ERROR ITMS-90125: "The binary is invalid. The encryption info in the LC_ENCRYPTION_INFO load command is either missing or invalid, or the binary is already encrypted. This binary does not seem to have been built with Apple's linker."

ERROR ITMS-90206: "Invalid Bundle. The bundle at 'EnvatoMiner.app/Frameworks/ReactKit.framework' contains disallowed file 'Frameworks'."

The resulting API analysis file is too large.  We were unable to validate your API usage prior to delivery.  This is just an informational message.

WARNING ITMS-90080: "The executable 'Payload/EnvatoMiner.app/Frameworks/Alamofire.framework' is not a Position Independent Executable. Please ensure that your build settings are configured to create PIE executables. For more information refer to Technical Q&A QA1788 - Building a Position Independent Executable in the iOS Developer Library."


#2 Frameworks Error

For Alamofire and ReactKit mess up do try use pod to handle Frameworks instead.


#3 Optimization Error

And for
ERROR ITMS-90125: "The binary is invalid. The encryption info in the LC_ENCRYPTION_INFO load command is either missing or invalid, or the binary is already encrypted. This binary does not seem to have been built with Apple's linker."
Try use Optimization Level  to both None


#4 Upload Eror

And guess what I failed to upload binary via Xcode 6.3 just like other , and yes export ipa did the trick


#5 Metadata Rejected

Now binary is up! But guess what!? Final boss is here! TADAAAA

Metadata Rejected
June 30, 2015
Information Needed We began the review of your app but aren't able to continue because we need additional information about your app. At


We began the review of your app but aren't able to continue because we need additional information about your app.

At your earliest opportunity, please review the following question(s) and provide as much detailed information as you can. The more information you can provide upfront, the sooner we can complete your review.

(1) Who is the intended audience of the app?
(2) What is the purpose of the app?
(3) Why does the app require an API key?
(4) Are there any costs associated with the API key?
(5) Are these tied to specific user accounts?
(6) How does the content of the app change with different API keys?

Once you reply to this message in Resolution Center with the requested information, we can proceed with your review.
Yes apparently Apple's reviewer didn't know anything about Envato API so they keep asking me mostly about user privacy concerning which pretty obvious (to me) in my case because Envato site have all this information provided but yeah just play along the rules. Don't forget to answer them nicely.


And here's new trick to save you a day or two

This clarify will took 1-2 days to ping-pong with reviewer so next time don't forget to add this information (1)-(6) right away while you submit via more information field!

PS: Want to know what I answer to the reviewer to get approval at 1st try? Wait until my app reach 100 downloads and I will reveal the hint! (Yeah, not again LOL)

As you can see it's a plenty things to learn and many problems to hit along the way, Just deal with it and happy coding!

Wednesday, July 1, 2015

[MQTT] Hello World Message Queuing Telemetry Transport Protocol



I'm trying to find something that (hopefully) better than regular socket and found
 MQTT Message Queuing Telemetry Transport Protocol  which Facebook choose to use it. So it should be good enough! let's try it! BTW This is boring terminal things, I blog it for reference later :D

First of all running some server (at local Mac) My first try is Mosquitto Let's brew it!
$ brew install mosquitto
Installing...
==> Installing dependencies for mosquitto: c-ares, libwebsockets
==> Installing mosquitto dependency: c-ares
==> Downloading https://homebrew.bintray.com/bottles/c-ares-1.10.0.yosemite.bott
######################################################################## 100.0%
==> Pouring c-ares-1.10.0.yosemite.bottle.tar.gz
��  /usr/local/Cellar/c-ares/1.10.0: 57 files, 540K
==> Installing mosquitto dependency: libwebsockets
==> Downloading https://homebrew.bintray.com/bottles/libwebsockets-1.4.yosemite.
######################################################################## 100.0%
==> Pouring libwebsockets-1.4.yosemite.bottle.tar.gz
��  /usr/local/Cellar/libwebsockets/1.4: 23 files, 3.3M
==> Installing mosquitto
==> Downloading https://homebrew.bintray.com/bottles/mosquitto-1.4.2.yosemite.bo
######################################################################## 100.0%
==> Pouring mosquitto-1.4.2.yosemite.bottle.tar.gz
==> Caveats
mosquitto has been installed with a default configuration file.
You can make changes to the configuration by editing:
    /usr/local/etc/mosquitto/mosquitto.conf


To have launchd start mosquitto at login:
    ln -sfv /usr/local/opt/mosquitto/*.plist ~/Library/LaunchAgents
Then to load mosquitto now:
    launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mosquitto.plist
Or, if you don't want/need launchctl, you can just run:
    mosquitto -c /usr/local/etc/mosquitto/mosquitto.conf
==> Summary
��  /usr/local/Cellar/mosquitto/1.4.2: 28 files, 700K
Try it!
$ mosquitto
-bash: mosquitto: command not found
Aww, command not found eh!?  Let see...

$ /usr/local/sbin/mosquitto
1433485808: mosquitto version 1.4.2 (build date 2015-05-08 13:55:22-0700) starting
1433485808: Using default config.
1433485808: Opening ipv4 listen socket on port 1883.
1433485808: Opening ipv6 listen socket on port 1883.
Hit ^C and use this magic
$ sudo ln -s /usr/local/sbin/mosquitto /bin/mosquitto
So we can start it properly now (let's call it terminal#1)
$ mosquitto
1433488093: mosquitto version 1.4.2 (build date 2015-05-08 13:55:22-0700) starting
1433488093: Using default config.
1433488093: Opening ipv4 listen socket on port 1883.
1433488093: Opening ipv6 listen socket on port 1883.
Then for client side I choose https://www.npmjs.com/package/mqtt
Let's new another terminal#2 to install and run it (you will need nodejs installed)
$ sudo npm install mqtt -g
Installing... (took sometime)
> bufferutil@1.1.0 install /usr/local/lib/node_modules/mqtt/node_modules/websocket-stream/node_modules/ws/node_modules/bufferutil
> node-gyp rebuild

child_process: customFds option is deprecated, use stdio instead.
  CXX(target) Release/obj.target/bufferutil/src/bufferutil.o
  SOLINK_MODULE(target) Release/bufferutil.node
  SOLINK_MODULE(target) Release/bufferutil.node: Finished

> utf-8-validate@1.1.0 install /usr/local/lib/node_modules/mqtt/node_modules/websocket-stream/node_modules/ws/node_modules/utf-8-validate
> node-gyp rebuild

child_process: customFds option is deprecated, use stdio instead.
  CXX(target) Release/obj.target/validation/src/validation.o
  SOLINK_MODULE(target) Release/validation.node
  SOLINK_MODULE(target) Release/validation.node: Finished
/usr/local/bin/mqtt_sub -> /usr/local/lib/node_modules/mqtt/bin/sub.js
/usr/local/bin/mqtt_pub -> /usr/local/lib/node_modules/mqtt/bin/pub.js
/usr/local/bin/mqtt -> /usr/local/lib/node_modules/mqtt/mqtt.js
mqtt@1.3.2 /usr/local/lib/node_modules/mqtt
├── inherits@2.0.1
├── xtend@4.0.0
├── minimist@1.1.1
├── commist@1.0.0 (leven@1.0.2)
├── readable-stream@1.0.33 (isarray@0.0.1, string_decoder@0.10.31, core-util-is@1.0.1)
├── mqtt-packet@3.2.0 (bl@0.9.4)
├── mqtt-connection@2.1.1 (through2@0.6.5, reduplexer@1.1.0)
├── end-of-stream@1.1.0 (once@1.3.2)
├── help-me@0.1.0 (pump@1.0.0)
├── concat-stream@1.5.0 (typedarray@0.0.6, readable-stream@2.0.1)
└── websocket-stream@1.5.0 (through2@0.6.5, duplexify@3.4.2, ws@0.7.2)
At terminal#2 and try subscribe
$ mqtt sub -t 'hello' -h 'test.mosquitto.org' -v
Got this at server terminal#1
1435683811: New connection from 127.0.0.1 on port 1883.
1435683811: New client connected from 127.0.0.1 as mqttjs_30eb07a2 (c1, k10).
New terminal#3 and try publish
$ mqtt pub -t 'hello' -h '127.0.0.1' -m 'from MQTT.js'
You will get this at  terminal#2
hello from MQTT.js
And got this on server side
1435683939: New connection from 127.0.0.1 on port 1883.
1435683939: New client connected from 127.0.0.1 as mqttjs_9fb1e1b2 (c1, k10).
1435683939: Client mqttjs_9fb1e1b2 disconnected.
Easy! Just some magic need and we good to go, Next post we will find ActionHero alike for this MQTT thing!

Happy Coding!

Friday, June 5, 2015

[Swift] ActionHero Client with Swift

Tadaa
Tadaaaaa 

Here's Swift version


client = AHClient()

client.on("alert") { message in println(message)}
client.on("api") { message in println(message)}

client.on("welcome") { message in self.appendMessage(message)}
client.on("say") { message in self.appendMessage(message)}

client.connect() {
    self.client.roomAdd("defaultRoom");
}

Compare to JS version

client = new ActionheroClient;

client.on('alert',        function(message){ alert( JSON.stringify(message) ) })
client.on('api',          function(message){ alert( JSON.stringify(message) ) })

client.on('welcome',      function(message){ appendMessage(message); })
client.on('say',          function(message){ appendMessage(message); })
client.connect(function(err, details){
    if(err != null){
        console.log(err);
    }else{
        client.roomAdd("defaultRoom");
        document.getElementById("name").innerHTML = "\"color:#" + intToARGB(hashCode(client.id)) + "\">" + client.id + "    }
});

Nice eh? :D

BTW : It's just proof of concept, no error/test, so heavy fork is need!
FYI : I'm moving on to MQTT , so don't expect any update so soon.
TL;DR : https://github.com/katopz/actionhero-client-swift

Happy Coding!