FatCamp: Win Bitcoin Cash Competing in 7 Day Fitness Challenges

Working on a new app idea called FatCamp that shares a lot of the code I’ve been writing for another project, WingsuitGP. Both of the apps are location based and revolve around competition, so the ideas are very much related when it comes to the code I’m having to write for both. I’m still sort of working the idea for FatCamp out in my head, but I wanted to jot down a few ideas here on the blog to help guide the creative process:
FatCamp: Win Bitcoin Cash Competing in 7 Day Fitness Challenges

  • The Challenge is simple, complete 5 workouts (bike or run) in 7 days and win BitcoinCash (100 mBCH)
  • Skip workouts, and we will fat shame you via text message reminding you to go work out
  • Accept Challenge
  • Start Workout
  • Receive BitcoinCash Prize Money via SMS with CoinText

Prize Money:

  • First 10 Users– 100mBCH ($12 Per User, $120 Per Week)
  • Next 100 Users– 10mBCH ($1.20 Per User, $120 Per Week)
  • Next 1000 Users– 1 mBCH ($0.12 Per User, $120 Per Week)

Paid Competitions:

  • Pay $12 – $120 Per Contest (Compete Against Strangers or Against Friends)
  • Friends (or Strangers) who miss workouts lose their entry fees, while those who don’t win money.

Inspiration: The Sober October Fitness Competition on the Joe Rogan Experience Podcast
UPDATE: I took my prototype FatCamp iOS app on a run tonight using an arm band and it wasn’t a very good experience at all. While there may be many more potential iPhone users than Apple Watch users, I think the experience on the Apple Watch would be a lot better. I honestly did not enjoy jogging around with the clunky arm band. I think the next step going forward is going to be rewriting the FatCamp prototype as a watchOS app.

 

How to Generate JSON Dynamically in Swift using Dictionaries, and then Send that Data Over the Internet using the Alamofire Networking Library/Wrapper for iOS

After a fruitful late night hacking session, I’ve finally figured out how to dynamically create JSON in Swift using dictionaries, and then how to send that JSON data over the network to a backend server running PHP. I’ve published something like five blog posts on this topic over the past week, but this is my final answer!
If you haven’t read any of my other posts on this topic, the problem which I kept running into was that I needed to generate a fairly large JSON object with an indeterminate number of items. So naturally, I needed to be able to generate the JSON dynamically using a simple for-loop. However, in Swift you need to generate your JSON using dictionaries which as you probably know, can only use strings for keys! How are you suppose to dynamically generate a large number of items without using numbers to identify the individual pieces of data? Well as one user on StackOverflow cleverly pointed out, you can simply turn your indices into strings by wrapping them in quotes! (Technically you call the String() method, but you get the idea). So 1 becomes “1”! That’s all there is to it.
So here it is, my final sample app demonstrating how to generate JSON with Swift and then send it over the internet to a backend server running PHP:
Single View (Main.storyboard)
SingleView
ViewController.swift

//
//  ViewController.swift
//  JSONxAlamofire
//
//  Created by Christopher Pedersen on 3/3/19.
//  Copyright © 2019 Christopher Pedersen. All rights reserved.
//
import UIKit
import Foundation
import Alamofire
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }
    @IBAction func onButtonClick(_ sender: Any) {
        let numberOfDataPoints: Int = 99
        // Note, numberOfDataPoints is actually an inaccurate name.
        // However, I don't have time to fix it right now.
        // The variable would be more accurately named something like
        // numberOfDataPointsMinusOne.
        var parameters: [String:Any] = [
            "numberOfDataPoints": numberOfDataPoints,
            "firstTypeOfData": [:],
            "secondTypeOfData": [:]
        ]
        var subDictionaryA: [String:Any] =
            [:]
        for i in 0...numberOfDataPoints {
            let indexAsString: String = String(i)
            subDictionaryA[indexAsString] = ["foo": Int.random(in: 1...100), "bar": Int.random(in: 1...100), "baz": Int.random(in: 1...100)]
        }
        var subDictionaryB: [String:Any] = [:]
        for i in 0...numberOfDataPoints {
            let indexAsString: String = String(i)
            subDictionaryB[indexAsString] = ["foo": Int.random(in: 1...100), "bar": Int.random(in: 1...100)]
        }
        parameters["firstTypeOfData"] = subDictionaryA
        parameters["secondTypeOfData"] = subDictionaryB
        Alamofire.request("http://wingsuitgp.com/networkingtest2.php", method: .post, parameters: parameters, encoding: JSONEncoding.default).response { response in
            if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
                print("Server Repsonse: \(response)") // print server response to console
            } else {
                print("ERROR: PC LOAD LETTER") // cryptic error message
            }
        }
    }
}


networkingtest2.php

// Receive JSON Data Via HTTP POST
$data = json_decode(file_get_contents('php://input'));
$numberOfDataPoints = $data->{'numberOfDataPoints'};
// Note, $numberOfDataPoints is actually a misleading name.
// Since the index starts at zero, this number is actually
// the highest number, but is not actually the number of data points.
// A more accurate name would be $numberOfDataPointsMinusOne.
// Don't have time to change the name of this variable right now so...
// o well!
if ($numberOfDataPoints connect_error) {
    die("Connection failed: " . $conn->connect_error);
}
// Insert First Type of Data into MySQL Database
for ($i = 0; $i {'firstTypeOfData'}->{"$i"}->{'foo'};
	$bar = $data->{'firstTypeOfData'}->{"$i"}->{'bar'};
	$baz = $data->{'firstTypeOfData'}->{"$i"}->{'baz'};
	$stmt = $conn->prepare("INSERT INTO networkingtest_table (datatype_column, foo_column, bar_column, baz_column) VALUES (?, ?, ?, ?)");
	$stmt->bind_param("siii", $datatype, $foo, $bar, $baz);
	$stmt->execute();
    $stmt->close();
}
// Insert Second Type of Data into MySQL Database
for ($i = 0; $i {'secondTypeOfData'}->{"$i"}->{'foo'};
	$bar = $data->{'secondTypeOfData'}->{"$i"}->{'bar'};
    $baz = 0;
	$stmt = $conn->prepare("INSERT INTO networkingtest_table (datatype_column, foo_column, bar_column, baz_column) VALUES (?, ?, ?, ?)");
	$stmt->bind_param("siii", $datatype, $foo, $bar, $baz);
	$stmt->execute();
    $stmt->close();
}
// Close MySQL Database Connection
$conn->close();
echo "data_received"; // echo server response back to client iPhone app

 

"Code is Power"– Naval Ravikant

I was listening to this great talk by Naval Ravikant tonight on YouTube after arriving back home in Dallas from a long day trip to Austin and back to see my son, and was getting ready to go to bed, but Naval has me fired up! It’s 1:30AM and I’m off to 7/11 to pickup some diet energy drinks and ready to do some late night hacking, because “code is power”:

“What can you do? What can you do that’s different. What can you do that’s better? What can you do that maybe the rest of the world is not willing to do? And one thing I would argue that more so than any other point in the history of our society, code is power. It is the new literacy. The personal computer is the most powerful tool ever invented by mankind since maybe the fire or the stone axe. And I would put it above the steam engine. I would put it above flight. I would put it above cars. I would put it above electricity. The reason is that all those other things were group efforts. You needed somebody else’s permission to use those tools. Even the printing press. No individual could run the printing press on their own. Or you would have publishers in the way. The personal computer and the internet are the first time since the invention of fire or the stone axe where you can do it all by yourself with nobody else’s permission.” — Naval Ravikant

 

Taking a Third Look at Creating JSON Friendly Dictionaries in Swift

So working with JSON in Swift has me stumped! I’ve been trying like hell to create large JSON objects in Swift but keep running into the same problem: Not everything you can write in pure JSON can be re-written with Swift Dictionaries. The networking libary which I’m currently using, Alamofire, expects you to write your JSON using Swift Dictionaries, and then the library/wrapper converts everything into JSON for you before sending it over the network using the HTTP POST method.
However, I think I’ve figured out the missing work-around. Well actually… someone on StackOverflow has figured out the missing work-around: How to make HTTP Post request with JSON body in Swift
Now, not everything in the blog post is relevant to what I’m trying to do as they are working with URLSession instead of Alamofire to handle the networking. But, I noticed one very interesting thing in the answers section that leads me to believe I’ve found the missing work-around. Here is how one StackOverflow user wrote his JSON:

let json: [String: Any] = [
    "title": "ABC",
    "dict": [
        "1":"First",
        "2":"Second"
    ]
]


Notice, he uses numbers for keys (as I would like to do) and is able to get away with this by cleverly wrapping the numbers in quotes to create a string! Sort of a hacked-together work around, but I think this is what I’ve been missing! Now all I have to do is cast the indexes in my arrays of data as strings and I’m good to go! Looks like things are headed in the right direction 🙂

 

Sending JSON Data from an iOS App to a Backend Server Running PHP with the Alamofire Networking Library/Wrapper

For the past several days I’ve been trying to figure out how to send JSON data from an iOS app to a backend server running PHP (using the Alamofire networking library/wrapper). The problem that I seem to keep running into is that working with JSON in Swift is sort of a pain in the ass. With Alamofire you are suppose to construct a dictionary to represent your JSON data, and then using the Alamofire.request method you can easily send your data accross the networking using HTTP POST.
However, I keep running into problems when attempting to generate my JSON data dynamically. For example, let’s say I want to create a JSON object that contains thousands of pieces of information. Swift doesn’t make that easy! So far I’ve only been able to get everything to work if my JSON data is all hard-coded, and not generated dynamically.
I feel like I’m getting closer to the answer, but still am not quite where I want to be. So far this is what I have:
Single View (Main.storyboard)
SingleView
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ViewController.swift

//
//  ViewController.swift
//  JSONxAlamofire
//
//  Created by Christopher Pedersen on 3/3/19.
//  Copyright © 2019 Christopher Pedersen. All rights reserved.
//
import UIKit
import Foundation
import Alamofire
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }
    @IBAction func onButtonClick(_ sender: Any) {
        let parameters: Parameters = [
            "firstTypeOfData": [
                ["foo": Int.random(in: 1...100), "bar": Int.random(in: 1...100), "baz": Int.random(in: 1...100)],
                ["foo": Int.random(in: 1...100), "bar": Int.random(in: 1...100), "baz": Int.random(in: 1...100)],
                ["foo": Int.random(in: 1...100), "bar": Int.random(in: 1...100), "baz": Int.random(in: 1...100)],
                ["foo": Int.random(in: 1...100), "bar": Int.random(in: 1...100), "baz": Int.random(in: 1...100)],
                ["foo": Int.random(in: 1...100), "bar": Int.random(in: 1...100), "baz": Int.random(in: 1...100)]
            ],
            "secondTypeOfData": [
                ["foo": Int.random(in: 1...100), "bar": Int.random(in: 1...100)],
                ["foo": Int.random(in: 1...100), "bar": Int.random(in: 1...100)],
                ["foo": Int.random(in: 1...100), "bar": Int.random(in: 1...100)],
                ["foo": Int.random(in: 1...100), "bar": Int.random(in: 1...100)],
                ["foo": Int.random(in: 1...100), "bar": Int.random(in: 1...100)]
            ]
        ]
        Alamofire.request("http://wingsuitgp.com/networkingtest.php", method: .post, parameters: parameters, encoding: JSONEncoding.default).response { response in
            if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
                print("Server Repsonse: \(response)") // print server response to console
            } else {
                print("ERROR: PC LOAD LETTER") // cryptic error message
            }
        }
    }

 
networkingtest.php

// Receive JSON Data Via HTTP POST
$data = json_decode(file_get_contents('php://input'));
$numberOfDataPoints = count($data->{'firstTypeOfData'});
if ($numberOfDataPoints <= 1) {     die("no data detected..."); } // Connect to MySQL Database $servername = "localhost"; $username = "DATABASE-ADMIN-NAME-GOES-HERE"; $password = "DATABASE-PASSWORD-GOES-HERE"; $dbname = "DATABASE-NAME-GOES-HERE"; $conn = new mysqli($servername, $username, $password, $dbname); if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}
// Insert First Type of Data into MySQL Database
for ($i = 0; $i < $numberOfDataPoints; $i++){     $datatype = "first_type_of_data"; 	$foo = $data->{'firstTypeOfData'}[$i]->{'foo'};
	$bar = $data->{'firstTypeOfData'}[$i]->{'bar'};
	$baz = $data->{'firstTypeOfData'}[$i]->{'baz'};
	$stmt = $conn->prepare("INSERT INTO networkingtest_table (datatype_column, foo_column, bar_column, baz_column) VALUES (?, ?, ?, ?)");
	$stmt->bind_param("siii", $datatype, $foo, $bar, $baz);
	$stmt->execute();
    $stmt->close();
}
// Insert Second Type of Data into MySQL Database
for ($i = 0; $i < $numberOfDataPoints; $i++){     $datatype = "second_type_of_data"; 	$foo = $data->{'secondTypeOfData'}[$i]->{'foo'};
	$bar = $data->{'secondTypeOfData'}[$i]->{'bar'};
    $baz = 0;
	$stmt = $conn->prepare("INSERT INTO networkingtest_table (datatype_column, foo_column, bar_column, baz_column) VALUES (?, ?, ?, ?)");
	$stmt->bind_param("siii", $datatype, $foo, $bar, $baz);
	$stmt->execute();
    $stmt->close();
}
// Close MySQL Database Connection
$conn->close();
echo "data_received"; // echo server response back to client iPhone app

 

 

App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure

“App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure”– quite the annoying error message eh? Okay, to fix this error and get on with your life using HTTP instead of HTTPS, you just need to add a little XML code to your Info.plist file and all will be well…
Add This Snippet of XML to Your Info.plist File (Github Gist) 
Reference This Complete Info.plist File For Context (Github Gist)

 

The Problem with Equity Crowdfunding

As the founder of an early stage startup (WingsuitGP), early stage startup funding is of great interest to myself. Isn’t that every aspiring internet entrepreneurs dream? To obtain that very first investment of outside capital, enough to quit your day-job and start working on your passion project full time.
With that in mind, I recently reached out to one of the big players in equity crowdfunding– AngelList backed Republic.co. Specifically, my question for the team at Republic was, “how much does it actually cost to raise money on Republic?” While it looks like many of the costs of raising money through equity crowdfunding portals can be deferred until after the fund raise is over, unfortunately the upfront costs (AKA onboarding costs) are substantial, somewhere between $3,000 to $10,000. And these upfront “onboarding costs” cannot be deferred until after a fund raise is complete.
So maybe this is why equity crowdfunding hasn’t really taken off yet. Raising $100,000 on the internet for your early stage startup sounds amazing. But once you throw in the $3,000 to $10,000 in costs required to run such a funding campaign, the idea seems significantly less appealing. Essentially, you need an outside investor first if you want to raise money on one of these crowdfunding portals. And more likely, you need fairly big first check in of initial seed investing. Because if an angel were to take a chance on you and write you a $20,000 check, why would you gamble half of that on a running an equity crowdfunding campaign that might fail?
And unfortunately, I think what these portals are actually ending up with are companies that have received a fair amount of initial funding, and are coming to the portals with their last $10,000 running hail-mary campaigns to try and cash in one last round of funding before their company implodes. I mean seriously, are there any hot startups raising money on these platforms? I could be wrong, but I think the problem is simple: The upfront “onboarding” fees that these portals charge are too high to make them competitive with raising money from traditional angel investors and startup accelerators like Y Combinator. Think about it, how many people would go through YC’s program if instead of receiving funding from YC and also getting the chance to pitch investors at demo day, the startups had to pay YC $3,000 to $10,000 for the chance to go and pitch at demo day? Startups don’t need expenses; they need investments. I honestly hope that the crowdfunding platforms get things figured out, but at the moment these fees are going to continue ensuring that they miss out on the up and coming startups and end up with all of the previously funded but now failing startups.

 

Marc Andreessen & Brendan Baker on Traction

Tonight I happened to stumble upon a great blog post from Venture Hacks titled What should I send investors? Part 3: Business Plans, NDAs, and Traction. The post cites two other blog posts, one from Marc Andreessen and another from Brendan Baker. I really wanted to read the aforementioned posts but unfortunately the links had long ago rotted away. Luckily I was able to find the posts elsewhere and just wanted to bookmark them here. Enjoy!
Part 4: The only thing that matters by Marc Andreessen
Startups: How to Communicate Traction to Investors by Brendan Baker

 

Taking a Second Look at Creating JSON Friendly Dictionaries in Swift

Earlier today I published a bunch of blog posts on how to create dictionaries in Swift that can easily be turned into JSON using the Alamofire networking library/wrapper for iOS. While I was trying to figure all of this stuff out earlier today I was primarily using the web based repl.it environment. However, after taking a second look at things it looks like using repl.it to do all of my testing may have been one of the big reasons why my solution ended up being much more complex than I would have imagined necessary.
After taking a step back and approaching the problem with a fresh perspective, it appears Alamofire has a built in class called “Parameters” which makes it easy to create JSON friendly dictionaries in Swift. Apparently however, I didn’t attempt to use this convenient class because I was doing all my hacking in the web browser and the actual Alamofire library and Parameters class was not available to me. So now I know: just use the Parameters class and creating JSON objects in Swift shouldn’t be all that complicated (maybe a little complicated, but not too bad).

 

Dynamically Generating JSON Friendly Dictionaries in Swift

As I’ve mentioned in my previous posts over the past couple days, I’m currently working on a new app that involves transmitting a fairly large amount of data from an iPhone app (WingsuitGP) to a backend web server. This is sort of backwards from what people are usually doing with JSON. Typically, JSON data is created by backend web services and then consumed by mobile apps. But in my case, my mobile app is the one creating the JSON data, and my backend web service is the consumer of the JSON data.
To transmit my JSON data over the network, I’m currently using the Alamofire http networking library/wrapper for iOS. With Alamofire, JSON data needs to be created first in the form of a Swift Dictionary which is then later converted to JSON format by Alamofire before being sent over the network via http.
One speed bump which I’ve run into so far is generating JSON friendly dictionaries in Swift dynamically. For example, lets say I have a large amount of data stored in the form of objects in my client-side Realm Database, how do I go about programmatically iterating over all of my data to dynamically create a Swift Dictionary that is also ready for conversion to JSON format by Alamofire? I’ve found some fairly straightforward examples on how to properly create JSON friendly swift dictionaries that are hard-coded, but I haven’t really been able to find any examples on how to dynamically create these dictionaries using an undetermined amount of data. So… here I present the solution I’ve hacked together today on repl.it (the solution shows the hard-coded method along with the dynamically generated method):

import Foundation
// REFERENCE: https://dzone.com/articles/all-you-need-to-know-about-json-with-swift
// Create a Hard-Coded Dictionary (JSON Friendly)
var myDictionary = [
    "location": [
        [
            "latitude": 30.00000001,
            "longitude": 30.0000005,
            "timestamp": 2342342342
        ],
        [
            "latitude": 30.00000029,
            "longitude": 30.00000023,
            "timestamp": 2342342343
        ]
    ],
    "altitude": [
        [
            "pressure": 90.00000001,
            "timestamp": 2342342345
        ],
        [
            "pressure": 91.00000029,
            "timestamp": 2342342347
        ]
    ]
] as [String:Any]
print("Hard-Coded Dictionary (JSON FRIENDLY)")
print(myDictionary)
print("")
// Create a Dynamically Generated Dictionary (ALSO JSON FRIENDLY)
var myNewDictionary = [:] as [String:Any]
var myLocationArray: [Int:Any] = [:]
myLocationArray[0] = [
    "latitude": 30.00000001,
    "longitude": 30.0000005,
    "timestamp": 2342342342
]
myLocationArray[1] = [
    "latitude": 31.00000001,
    "longitude": 31.0000005,
    "timestamp": 2542342342
]
var myAltitudeArray: [Int:Any] = [:]
myAltitudeArray[0] = [
    "pressure": 90.00000001,
    "timestamp": 2342342342
]
myAltitudeArray[1] = [
    "pressure": 91.00000001,
    "timestamp": 2542342342
]
myNewDictionary["location"] = myLocationArray
myNewDictionary["altitude"] = myAltitudeArray
print("Dynamically Generated Dictionary (ALSO JSON FRIENDLY)")
print(myNewDictionary)