Categories
Featured iPhone app

Send Email via Cloud Code in Parse

Reading Time: 2 minutes

(Update 05-10-2016) Came across this post about hosting your own Parse server from raywenderlich.com

(Update 01-28-2016) All good things came to end (see today’s Facebook announcement on shutting down Parse on January 28, 2017, a year from today). They also listed migration path. A lot discussion on reddit on this topic. Also a tutorial on Firebase by raywenderlich, note Firebase is owned by Google (they are also famous for shutting down things 🙂

(Update 10-12-2015) Here is the “get started on Cloud Code“. This talks about how to set up the Parse cloud code (including email), the integration with Mandrill is also there. You will need two accounts (both are free for small apps): Mandrill and Parse. Just replace the keys in my code below and in the parse command with your own keys. I also create a github repo here. It has a README just like this blog post and has all the cloud code.

(Original 11-24-2013)
The cloud code (javascript)
refer to this stackoverflow thread; and this Parse documentation. Note I used ManDrill (free for up to 12,000 mails per month), the main things I noticed is they requires 10 letters password, and the API key can be created in Settings (this will be used later, we will use API key instead of SMTP server)

cat ./cloud/main.js

// Use Parse.Cloud.define to define as many cloud functions as you want.
// For example:
Parse.Cloud.define("hello", function(request, response) {
response.success("Hello world!");
});

Parse.Cloud.define("sendMail", function(request, response) {
var Mandrill = require('mandrill');
Mandrill.initialize('12AkxxxxxxxxxxxxxxrZEg');

Mandrill.sendEmail({
message: {
text: request.params.text,
subject: request.params.subject,
from_email: request.params.fromEmail,
from_name: request.params.fromName,
to: [
{
email: request.params.toEmail,
name: request.params.toName
}
]
},
async: true
},{
success: function(httpResponse) {
console.log(httpResponse);
response.success("Email sent!");
},
error: function(httpResponse) {
console.error(httpResponse);
response.error("Uh oh, something went wrong");
}
});
});

To test it out, do the “parse deploy” after put the code above in main.js (under cloud dir), then issue this command:
curl -X POST -H "X-Parse-Application-Id: your-parse-application-id" -H "X-Parse-REST-API-Key: your-parse-REST-API-key" -H "Content-Type: application/json" -d '{"toEmail":"major_xu@yahoo.com","toName":"Major Xu","fromEmail":"minjie.xu@gmail.com","fromName":"Minjie Xu","text":"testing ManDrill email","subject":"this is just a test"}' https://api.parse.com/1/functions/sendMail

Objective-C code
Refer to Parse documentation here. Note this is a simple “Hello World” example.
[PFCloud callFunctionInBackground:@"hello"
withParameters:@{}
block:^(NSString *result, NSError *error) {
if (!error) {
// result is @"Hello world!"
}
}];

My email code is a bit more complex compared to “HelloWorld” 🙂


[PFCloud callFunctionInBackground:@"sendMail"
withParameters:@{@"toEmail":toEmail,@"toName":@"Minnjie Xu",@"fromEmail":@"uudaddy@gmail.com",@"fromName":@"uudaddy",@"text":@"resetPasswordButtonPressed...",@"subject":@"myNestEgg ~ testing ManDrill email"}
block:^(NSString *result, NSError *error) {
if (!error) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Reset Passoword" message:@"Email Sent :-)"
delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil];
[alert show];

}
}];

Categories
advice and tips iPhone app

Two good articles on touch screen generation

Reading Time: 2 minutes

Atlantic

CS monitor

My take:
My daughter is 3 and half years old. My wife had iPhone (3g) before she was born, and I bought iPhone 4 when she was 6 months old. Then comes the iPad (1), and currently I have an iPad mini, and my wife has iPad 4. I spent about $30 buying apps for my daughter (mostly Toca Woca and Sigo Mini; also raywenderlich WildFable; and I see Ewe, I Hear Ewe). I felt the latter is better suitable for toddlers, while the former ones are more like games (which I have some reservations).

My observations on iPad app and screen time: my daughter also watches Netflix kids TV/Youtube for about half an hour a day. We tried pretty hard to make sure she did not watch too much TV before she was two (again, this is mostly from hearing her teachers’ advice; and from reading the articles about TV’s effect on growing children).

My thoughts:
1) Moderation, moderation, moderation. It’s not easy. I know, we all have been there. Grabbing iPad/iPhone from crying toddlers. “5 more minutes”. But we need to be firm. Otherwise the 5 more minutes will means 15 more minutes. And the flood gates started here. I found out, if I’m consistent, and if the child is tired of the silly game/TV, and if we can provide a better alternative (reading books, something more fun), she gives up iPad quickly.

2) Engagement, engagement, engagement. When she was very young (probably around 2), sometimes we let her watch the “Curious George” on Netflix, together with parents. And she will have a lot of questions. In that sense, watching TV is not purely passive, and that’s a good thing. Same can be said of reading/listening the wild fable, and the I see Ewe/I hear Ewe.

Categories
iPhone app

Some roadblocks and tips when updating app for iOS 7

Reading Time: 2 minutes

Recently I’ve worked on updating one of my app to make it works on iOS 7, and have encountered some roadblocks.

Push view controller
problem/symptom: the new view controller pushed from old view controller shows no content, on iOS 7. It works fine on iOS 6.1 (the deployment target is still iOS 6.1).

solution/diagnose: I found the following code snippets by Sourabh Kumbhar at mobinett very handy when debugging those kinds of issues.

Put the following in the viewDidload of the view controller got affected by iOS upgrade.
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7)
{
self.edgesForExtendedLayout = UIRectEdgeNone;
}

Back to the original problem. Animation problem? I did quite a few googles trying to find out if the animation change is the cause here, but to no vail. Depends on the view, fix it in viewWillAppear or use NSNotification to make sure the viewDidLoad calls after the view property gets reset (web view).

Old code
MarketDetailViewController *marketDetailViewController =
[[MarketDetailViewController alloc] initWithNibName:@"MarketDetailViewController" bundle:nil];

// Set the title of the detail page
[marketDetailViewController setTitle:product.name];

// Push the detail controller on to the stack
[self.navigationController pushViewController:marketDetailViewController animated:YES];

// Populate the details
[marketDetailViewController setLabelsForProduct:product];

-(void) setLabelsForProduct: (Market*) theProduct
{
NSLog(@"inside setLabelsForProduct, time =%@", theProduct.time);

// Set the text of the labels to the values passed in the Product object
[nameLabel setText:theProduct.name];
[manufacturerLabel setText:theProduct.city];
[detailsLabel setText:theProduct.state];
[priceLabel setText:theProduct.phone];
[quantityLabel setText:theProduct.produce];
[daysLabel setText:theProduct.days];
[self.timeLabel setText:theProduct.time];
[startDateLabel setText:theProduct.startDate];
[endDateLabel setText:theProduct.endDate];
[emailButton setTitle:theProduct.email forState:UIControlStateNormal];
[webButton setTitle:theProduct.web forState:UIControlStateNormal];
}

New code
- (void) viewWillAppear:(BOOL)animated{
NSLog(@" MarketDetailViewController::viewWillAppear");
[super viewWillAppear:animated];

[nameLabel setText:theMarket.name];
[manufacturerLabel setText:theMarket.city];
[detailsLabel setText:theMarket.state];
[priceLabel setText:theMarket.phone];
[quantityLabel setText:theMarket.produce];
[daysLabel setText:theMarket.days];
[self.timeLabel setText:theMarket.time];
[startDateLabel setText:theMarket.startDate];
[endDateLabel setText:theMarket.endDate];
[emailButton setTitle:theMarket.email forState:UIControlStateNormal];
[webButton setTitle:theMarket.web forState:UIControlStateNormal];
[self.view setAlpha:1];
}

-(void) setLabelsForProduct: (Market*) theProduct
{
NSLog(@"inside setLabelsForProduct, time =%@", theProduct.time);
...keep all those setters here...otherwise it will break iOS 6.1
theMarket = theProduct;
}

Web View
Similar idea, but I used NSNotification to fix the problem in iOS 7.

self.webViewController = [[WebViewController alloc] initWithNibName:@"WebViewController" bundle:nil];
// Set the title of the detail page
[self.webViewController setTitle:[nameLabel text]];

[self.navigationController pushViewController:self.webViewController animated:YES];

NSLog(@"[product web] = %@", [[webButton titleLabel] text]);

// The following works in iOS 6.1, but no longer in iOS 7
//[webViewController refreshView:[[webButton titleLabel] text]];

add the following to the viewDidLoad of parent view controller
// Listen for new image uploads so that we can refresh the image wall table
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(webPageDownloaded:)
name:N_WebPageDownloaded
object:nil];

In the web view controller, viewDidload, add
[[NSNotificationCenter defaultCenter] postNotificationName:N_WebPageDownloaded object:nil];

refreshView is the same:
-(void) refreshView:(NSString*)webAddress0
{
self.webAddress = webAddress0;
[self.myWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:webAddress0]]];

CGRect textFieldFrame = CGRectMake(kLeftMargin, kTweenMargin,
self.view.bounds.size.width - (kLeftMargin * 2.0), kTextFieldHeight);
UITextField *urlField = [[UITextField alloc] initWithFrame:textFieldFrame];
...some code to render the urlField, omit for the sake of readability...
[self.view addSubview:urlField];
}

// the call back being called when posting Notification
- (void) webPageDownloaded:(NSNotification *)notification
{
[self.webViewController refreshView:[[webButton titleLabel] text]];
}

Code signing
symptom: when submit to app store, it will say no valid provision profile can be found. In some cases Xcode will crash for that project. If the user tries to submit an ad-hoc package (ipa file) via Application Loader, Apple will send “invalid signature” email right away, reject that binary. And I found following solution at stackoverflow.com
old distribution provision profile no longer work, create a new one for Xcode5

Categories
iPhone app

A collection of iOS dev tutorial guide

Reading Time: < 1 minute

Arguably iOS 7 bring most drastic changes to iOS in last 3 to 5 years. With new features like dynamics in UIKit, (more/new) auto layout, it creates both opportunities and challenges for developers. But I know the Mac/iOS developer community is best, in terms of sharing knowledge. With the iOS 7 out just 2 weeks ago, I already see some good iOS 7 dev tutorial and guides.

Tristan O’Tierney ‏@tristan recommend this one by @ashfurrow. Note Tristan is one of the early iOS developer for Square. Ash Furrow is an iOS developer @teehanlax.

Essential iOS 7 developers guide by Double Encore
Remember seeing those guys (guys wearing their T-shirt) at one of the iOS dev conference (Voice that matter, Fall 2010 at Philly).

RayWenderlich.com iOS 7 by tutorial
This is probably the most comprehensive and the best iOS tutorial in the market. Ray started this tradition from iOS 5 (so this is three years in a row). Note Ray has also published a few shortened version of selected tutorials in the iOS 7 tutorial feast (free).

I will add more as I see fit.

Categories
iPhone app

iPad in classroom

Reading Time: < 1 minute

Good idea? Bad idea? I read this article on LATimes talking about how the kids hacked the MDM software on school issued iPads. The topic was on security. Obviously the MDM provider did not do a through job, as explained by an article on alertboot here.

This reminds me of another question, the iPad in classroom. A while ago I recall seeing a plea at my local school website, the kids there asked parents/friends donation, to buy them iPad, so that they can do cool things like count coins on iPad. My take then is why not counting the real coins. I can understand the pitch from educators (such as this one at LAUSD), the blah blah (perceived good things are going to happen with the iPads). At the end of the day, those devices have to be used to enhance the kids learning, not to distract their learning, or to reduce teachers’ creativity.

(Update 10-02-13) Tom Kaneshige of CIO magazine has a more comprehensive explanation of MDM and why the incident happened.

Categories
iPhone app

iOS 7 first impression #iOS7transition

Reading Time: < 1 minute

(Update 09-27-13) I think it’s a bit silly people are all over the motion-sickness caused by iOS 7. I found the new Safari “color effect under address bar when the web page moves up” cool, it took me a while to figure out why the color on the top is changing sometimes (very subtle 🙂

(Original 09-25-13) I updated my iPad mini from iOS 6.1.2 to iOS 7 (upgrade to 6.1.3 first) in the weekend, when I saw the tide is turning to iOS 7 for the iDevices 🙂

Some impressions
Motion fact, when one rotate or moves the iDevice, cool;

Warm and fuzzy (screen saver, password screen), control center;

Enterprise deployment change (ad hoc deployment now checks version/bundle number);

App: Zite, the close article (x check mark) is at bottom left, previously user tap background, note the new icon for sharing;

Safari, again note the new icon for sharing, bookmark, history.

By the way, I am tweeting some of my iOS 7 observations on twitter using #iOS7transition.

Categories
Fun iPhone app

Almost there ~ my 1st impression on Nexus 4 and Android 4.2.x

Reading Time: 2 minutes

(Update 2, 11-18-2013) I sold my Nexus 4 as I am getting my iPhone 5s. I still think Nexus 4 is a lot phone for the money ($199 before tax). Another feature I liked is the integration with google contacts, and google+ photo backup. I just found there’s an option on iPhone Google+ app for backup now.

(Update 09-16-2013) I agree with @PhillRyu that the back button on Android is nice, along with the multi-task button, it separate tasks from the home button (the iOS home button is a bit overloaded, it does both back and home, and double click home brings up the multitask thing).

(Original 09-08-2013) Last week I got my 1st Android phone, the Google Nexus 4. I bought it primarily due to its lowered price (from $299 to $199 before tax), and my 3 year old iPhone 4 battery is doing down hill (found a trick to save it after I bought the Nexus 🙁

I tweeted some minor problems/questions I have with Nexus 4/Android since then. Again for the most part, I am happy with the screen size, battery life (being new), and the sharpness of android in general. A few things I mentioned/complained in twitter:

1) Lack of a native Mail app, in iPhone I can add all the mailbox (yahoo mail, gmail) to the Mail app, in Android there is not a good very native app. But later I noticed the notification feature kinda compensated it. I did install the Yahoo Mail app. The Gmail comes by default.

2) Again on the email things, for some html formatted email, it appears iPhone can scale it properly the first time when the user opens it, on Android, it did not get right the first time. The workaround is move the mail left, then zoom (make it a bit smaller to fit in the screen). Not a big deal.

3) A bit sneaky: the Android recommend feature, in Youtube, Play store (music). Also the photo upload (to Google+).

4) Chrome web browser does not have a “reader” feature like Safari does: for better reading experience (filter out ads, and scale the web page).

5) Share it feature: initially I thought it only has the gmail, google+…after I installed the facebook and yahoo Mail, I found those are also available.

Categories
Fun iPhone app

iTunes, iCloud, Dropbox, wd 2go

Reading Time: < 1 minute

Krugman, the Nobel economics laureate recently penned an article basically saying Apple is no good. I think he has one valid point on iTunes and the relatively closeness of Apple ecosystem. This reminds me of one thing, the cloud storage for consumers. Apple has this iCloud going for a few years, it can be used to back up iDevices (photos, videos, documents, etc.), but not as flexible as Dropbox (or Box.net, and many others), both Apple and Dropbox has the subscription plan, for iCloud, it’s $20 for 10Gb additional (5Gb is free) per year, and for Dropbox, it’s $10 for 500 GB per month (2Gb is free, and there are other ways to earn free storage).

Then I came across this wd 2go, it is probably the cheapest (if we ignore the electricity, and bandwidth cost), basically it’s free with the WD My Book Live purchase. My Book Live costs about $129. There is no recurring fees. I have not got this one yet, but I’m thinking about it as I have 2 iPhones’ worth of pictures/videos, and need to store it someway. Was wondering if I could just transfer from iTunes to the WD My Book drive.

While I went through all these, what’s my point? Personally I think the openness rankings of those 3, from most close to open: iTunes/iCloud, Dropbox, wd 2go. Of course I understand one can argue security wise, the ranking might be different 🙂

Categories
iPhone app

iOS training classes in St. Louis area

Reading Time: < 1 minute

Disclaimer: not including any commercial providers here, as they are usually more expensive. With today’s online learning resources (raywenderlich.com tutorial, stackoverflow to say a few), it’s fairly straightforward for an experienced developer to pick up Objective C and UIKit, etc. I think the value of classes is mostly from interaction with instructors, and do some real life projects.

wustl

slu

umsl

St. Charles Community College

Last but not least, the St. Louis iOS group led by Brian Coyner. The format is different from the training class, but it’s a good place to hang out with fellow iOS developers in the area. For that matter, there is a mobile dev group with an emphasis on Android (led by Heath Borders) as well.

Categories
iPhone app

iOS 7 articles

Reading Time: < 1 minute

http://mattgemmell.com/2013/06/12/ios-7/

http://blog.mengto.com/ios-7-transition-flat/

http://designmodo.com/flat-design-principles/

http://www.marco.org/2013/06/27/ios7-as-defense

http://whoo.ps/2013/05/12/flat-design-is-great-for-mediocre-designers-like-me