'Voice lessons' are what actors, politicians, etc. take to make themselves sound authoritative - teaching cadence, intonation, vocal range, emphasis, accents, etc. You should be able to find them at acting schools or local community colleges, but there are a lot of freelance coaches out there. You might also find them under "voice coach" or "vocal instruction". Actually, taking acting lessons may be worth it as well.
When one of my apps was pirated a few years ago, I became extremely interested in iOS security. Based on my knowledge, I can vouch for the accuracy of the article you linked to.
The article explains quite well what IAP makes secure and what it does not. If you are using IAP to deliver content stored on Parse, Parse's SDK (and server code) makes this process very secure. The attack goes like this:
1) the attacker fakes receipt and sends it to Parse hoping that Parse will deliver the content,
2) Parse will send the receipt to Apple and ask if the receipt is valid and indeed for the product that is being requested,
3) Apple will acknowledge that this receipt is fake or for a product not being required,
4) Parse rejects the request, and no content is delivered. Success.
However, if you are using IAP to unlock features that are already shipped with the app, IAP does not prevent against binary manipulation attacks.
Awesome, in theory this is how it should work. I'm actually more curious as to how you handle it practically though. Because for us, validating the receipt from Apple takes time, so if you are first making a request to Parse and then Parse has to make a request to Apple, the added latency poses a real threat to the user cancelling the transaction, especially on a mobile device with a crappy connection. This is why I see server-side validation as non-ideal. But such is the state of mobile development.
Most of the jail broken cracks are trivial to detect client side. Otherwise... They aren't going to pay anyway, might as well make the experience better for payers and not block on validation( but still track invalid transactions). And besides, if they're willing to install a hackers DNS server and ssl cert, they won't have money for long.
I agree. The hackers will only be a small percentage of your user base (guessing <=5%), if you have a problem at all. This issue is more problematic if you track revenue metrics, and so JB users may inflate your numbers considerably, if you're not cognizant.
Officially we should not be commenting on iOS 6 given the non-disclosure nature of the preview. Maybe I can discuss what Parse offers that would be difficult for anyone else (Apple/Google/Amazon) to match:
1. iOS 4, iOS 5 compatibility. Today, the most common iOS development target platform is still iOS 4. Using Parse your in-app purchase will be able to work for the customers who are not on the newest iOS platform.
2. Attaching metadata for products. At Parse a lot of our customers want to attach metadata information to products (categories, authors, genres, the publishing date, actors, etc) and to query products based on this information. You can imagine this is a very handy feature for an app that sells comic books. This is very natural to do on Parse because Parse offers a query-able, key-value data store. In fact, anyone, with or without technical background, would be able to use the data browser to add the metadata to the Product class.
3. Hosting content on Parse requires no App Store review, thus introducing no delay/resubmission via iTunes Connect.
4. Hosting content on Parse has no limit on the number of files/total size of files.
5. Cross app-store in-app purchase hosting. At Parse we see a lot of developers making the same app for Android and iOS. By hosting the content on Parse, you can use Parse for both your iOS and Android app. Parse would know how to validate the purchase receipt against iTunes Connect, Google Play, Amazon AppStore, and other App Stores. Currently Parse does not offer Android support, but we would be able to do this if there is sufficient demand.
>> 3. Hosting content on Parse requires no App Store review, thus introducing no delay/resubmission via iTunes Connect.
I think that's incorrect unless you are not selling the content through IAP. You would still need to create an IAP product in order to complete the iTunes IAP receipt validation.
However, for most games, it's designed so users buy virtual currencies and content purchases are not directly tie in to IAP products.
You are correct in that you would need to create your product and get your product approved. However, the product's associated content does not need to be approved. It is my understanding some App store (not necessarily Apple) in the future may require the content itself be reviewed.
Does Parse support Newsstand yet? I mean in an easy-to-set-up-we-already-did-everything-for-you way, not just in a "yeah, you can use Newsstand with Parse" sort of way.
Newsstand also includes background downloading, issue management and an issues list. Some sort of library is also needed, so users can see what they have downloaded and what is on the device. Most indie developers I know struggle with these things if they don't use a pre-packaged publishing suite, like Adobe Digital Publishing or Magster.
Most Newsstand apps are made by larger media companies because they have the money to make them. Indie developers aren't on Newsstand too much right now because we can't figure it out. My own magazine is just an app for the iPad without Newsstand support, and I know a lot of other magazines masquerading as apps when they really should be in Newsstand.
I think if you were to simplify things you would find a large market. Almost every magazine I've seen handles Newsstand the same way, its very standardized, which is perfect for you guys. Despite being standard, the code is frustratingly complex and difficult to implement. You might not see it now because the people that publish magazines aren't necessarily the coders you talk with every day. But small publishers, indie e-zine publishers and other periodical publishers (online and off) know the future is on places like the iPad, they just can't find someone experienced enough to code it from scratch for a low price. They live in a print or online world and iOS developing is a black box.
Just glanced through SDWebImage's source code. Think this is quite similar to AFNetworking's UIImageView category. My comment below should also apply here.
In the Parse framework, the equivalent class is PFImageView. We chose to design our API differently; from my experience, I believe the assignment of the web image to load and the actual download of the images should be two different steps. This is evident in UITableViewController. In tableView:objectForRowAtIndexPath:, the app developer should know which URL to load, but we should not load the images at this point. Although you CAN achieve the same goal via the other two libraries' API, I feel strongly the API becomes more intuitive to use when the two steps are broken apart.
By the looks of it, Parse is still downloading the image as the table view scrolls (that would be only reasonable). The behavior of not displaying until the table stops moving would appear to be a shortcoming of Parse not executing its operation using NSRunLoopCommonModes. AFNetworking gets this right.
Hi Mattt, in PFQueryTableViewController, the downloading does not start until the scrolling stops. We chose to do this because we wanted the default loading behavior to be very passive. You could verify this is indeed the behavior from the animated gif - the network activity does not start until the table finished scrolling.
Sunsu, thanks for the awesome feedback. We do think this is a great addition. After all, PFQueryTableViewController is about loading data stored on Parse; and if a developer has images stored on Parse, we should be able to load them and display them in the controller.
Let me know what other things would be great to have!
Currently, it loads the onscreen images when the scrolling stops (which is a non-aggressive loading behavior). If you wish to be more aggressive about loading the images, i.e. loads the images when the scrolling starts to decelerate, or loads the images as soon as the table scrolls (very aggressive), you can fine control the loading behavior via the loadInBackground method in PFImageView (the PFTableViewCell has a PFImageView as its imageView property).
In designing the API, I debated whether I should introduce a property that lets developer specify a loading behavior from a default set. I chose not to expose it for now and wait for some feedback; if this is a commonly asked feature, I can always introduce it later. I find, in the personal apps I build, this loading behavior is sufficient for 90% of them. Would love to hear others' feedback, though.
Cool, thanks for the info, makes sense. I also prefer to do non-aggressive loading as a dev, but for some of my apps I got lots of feedback from users that loading images that way "felt slow and laggy" since they are used to aggressive loading in other apps...
Exactly. To be aggressive in loading is kind of risky since doing it poorly can lead to a non-responsive behavior in the app. App developers can always choose to be more aggressive if the default behavior is not aggressive enough, but if the framework chooses to be overly aggressive, it prohibits some apps from adopting the framework.
I have not seen SDWebImage. From what I can recall about AFNetworking (a fantastic library, by the way), it provides a category on UIImageView whose methods can download and display web images. I don't think it provides any help for loading images in a UITableViewController context. In other words, the app developer still needs to state what URL to load and when to load the images. With PFQueryTableViewController, you just state which image each cell should load, and the loading is managed by the controller.
SDWebImage provides a nifty category extension UIImageView+WebCache which provides a setImageWithURL:placeholderImage: method on UIImageViews and uses the SDWebImageCache to cache the images locally for you. It is excellent and I use it everywhere.
AFNetworking provides a similar category extension, but there is no obvious way to make it use an ondisk cache that survives app restarts, so its caching is not as useful as SDWebImage's.
Yes, There is disk caching for NSURLConnection by default, but in my experience it does not cache it across app restarts, so each time the app starts again all the images have to be fetched all over again... SDWebImage gives the persistent disk caching I want.
If I'm misunderstanding what's happening please let me know...