

Parse Announces Large File Support and Facebook Users - tikhon
http://blog.parse.com/2011/10/24/facebook-users-and-files/?#1

======
bjtitus
I recently integrated Parse in my application only to run into a huge wall.

I implemented the Relational Data as described on the site but failed to
realize that it is not possible to drill down into these relationships in
queries. I want to be able to find objects with a related object where
something is true. Obviously, I could rearrange my data in such a way to work
with Parse's existing offerings but it would require more processing when
importing the data than I'd prefer.

Unfortunately, this has turned me off from Parse and I'm now beginning to look
at other solutions like StackMob even though they have no client side caching
(I can implement my own using something like RestKit).

Is there any status on being able to drill into relationships in PFQuery?

~~~
csmajorfive
Sorry to hear you had a bad experience. There's plenty of things Parse is
still missing and this is definitely one of them. We're working on it!

~~~
bjtitus
Sorry to phrase it poorly.

It was actually quite a great experience. More of my lack of thoroughly
researching the query capabilities. Everything from integrating the SDK to
importing data went very smoothly.

I realize this is not a top priority feature since it isn't too difficult to
work around it in most cases. Any idea on a time frame?

------
nupark2
Parse's reliance on globals (singletons) grates on my quite a bit, and has
largely prevented me from bothering to read further. [1]

I think of global variables as a cardinal sin of OO API design. They create
unnecessary dependencies, lock down architecture, and reduce/eliminate
composability.

Taken to the extreme demonstrated in Parse, they remove most of the advantages
of using an OO language that supports polymorphism.

[1] That, and serious questions about whether something so general purpose can
adequately meet the needs of anything but the most basic application. For
instance, the lack of schemas and the lack of server-side code means that
upgrading of data (and validation of data) is pushed to the client-side
application. I'm not sure I'd like to be the one debugging the kinds of issues
that arise when you have different end-user application versions potentially
corrupting one another's data.

[Edit] Can someone that's downvoted me into the serious negatives please
explain what portion of my architectural / API / OO arguments they disagree
with? This perfectly reasonable technical complaint was also voted into the
negatives (I just voted it up), which implies some odd voting behavior by
Parse proponents: <http://news.ycombinator.com/item?id=3151570>

~~~
csmajorfive
What singletons are we using besides one for the current user?

I think you may be confusing singletons with class methods.

~~~
nupark2
I was actually referring to the use of global variables (but I'll tackle the
class method issue below). Take, for example, this instance (not class)
method:

    
    
      -[PFObject delete];
    

Where is the object deleted from? Where was it created? It uses a global
variable to achieve this behavior.

Likewise, there are methods like:

    
    
      +[PFObject saveAll:]
    

This also relies on a global variable somewhere to do its magic. Where are the
objects saved? How do I interject different behavior? How do I modify the
behavior for a specific subsystem of my application?

That said, I can also address the use of class methods. Similar to how
singletons make it quite difficult to leverage OO polymorphism and decoupled
architecture, class methods literally throw away OO polymorphism by providing
direct bindings to what amount to global functions.

One can not leverage polymorphism with class methods, as the bindings are
direct and fixed -- one can not modify the behavior of class method by
configuring a specific instance (since there's only one global instance). One
also can not modify the behavior of a method by providing a different instance
that conforms to the required protocol.

~~~
csmajorfive
You're right, delete is an instance method. You call it like so: [myObject
delete];

So the object referred to by the variable myObject gets deleted from our
servers. It was created whenever it was instantiated using a query. What
global is it using?

saveAll is a static (class) method. It takes in a collection of instantiated
objects and saves them to our servers. What global is it using? As for
interjecting custom behavior, perhaps you're missing that all of these methods
take in a variety of callbacks that can modify behavior.

~~~
nupark2
_So the object referred to by the variable myObject gets deleted from our
servers. It was created whenever it was instantiated using a query. What
global is it using?_

How does myObject acquire a reference of some kind to your servers, and the
context in which it is stored? (That's the answer).

 _saveAll is a static (class) method. It takes in a collection of instantiated
objects and saves them to our servers. What global is it using? As for
interjecting custom behavior, perhaps you're missing that all of these methods
take in a variety of callbacks that can modify behavior._

How do I arbitrarily modify the saveAll method so that I can perform
_arbitrary_ operations on objects before they're saved, so that I can
implement a custom undo manager (but only when working on objects in the
context of the user editing the document. Elsewhere I want different
behavior)?

\----

These approaches (class methods, singletons/globals) are breaking OO
polymorphism, and significantly hamstringing your APIs.

I'll try to provide an example that might matter to you:

Let's pretend that I want to add support for sharing data between users of my
application. It's important to me to not repeat myself, so I want to have the
same code be able to write data to the user's personal storage, write data to
_one of several_ possible shared storage destinations.

You decide you want to support this API. How do you make your current
global/singleton API work for me?

~~~
csmajorfive
The hostname of our servers is indeed hardcoded in the framework. So, yes,
that's a 'singleton' in the same way that configuring your database hostname
in Rails is a singleton.

So far our developers have had a lot of success building upon Parse. There are
certainly some missing pieces (like the one pointed out in another comment on
this post) but none of them have related to our overall architecture.

I invite you to let us know what it should look like ideally at
founders@parse.com or even stop by our office. We love to talk with
developers.

~~~
nupark2
_The hostname of our servers is indeed hardcoded in the framework. So, yes,
that's a 'singleton' in the same way that configuring your database hostname
in Rails is a singleton._

I get the impression that arguing this further is a dead end. I'd suggest
looking at NSManagedObjectContext for a basic approach that doesn't rely on
global state / global variables, and while imperfect in many ways, is at least
familiar to existing ObjC developers.

Lastly, I'd look into the research into the effects of global variables on
program interdependence, as well as the numerous discussions on the negative
impact on maintainability, composability.

Regardless of the above, it sounds like Parse will likely not be a good fit
for our (large, complex, and top-chart) applications. If we're not the target
audience, then no problem.

~~~
lacker
We did look at NSManagedObjectContext... but NSManagedObjectContext _doesn't_
support polymorphism.

[http://developer.apple.com/library/mac/#documentation/Cocoa/...](http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/CoreDataFramework/Classes/NSManagedObjectContext_Class/NSManagedObjectContext.html)

 _You are strongly discouraged from subclassing NSManagedObjectContext. The
change tracking and undo management mechanisms are highly optimized and hence
intricate and delicate. Interposing your own additional logic that might
impact processPendingChanges can have unforeseen consequences._

~~~
nupark2
_We did look at NSManagedObjectContext... but NSManagedObjectContext doesn't
support polymorphism._

Yes, it does. For a few reasons:

1) It is passed around as an _instance_ , not a _global variable_ , and as
such, each instance can be individually configured to behave differently (such
as with a different persistence implementation), while still responding to
defined API.

2) NSManagedObjectContext _can_ be subclassed.

3) Apple can improve the implementation (and recommend subclassing in the
future) without breaking or modifying any existing client code.

You're confusing 'polymorphism' with subclassing. Related, but not the same.

\---

Now, I did say that NSManagedObjectContext has many flaws -- and it does, but
they're largely unrelated to the _use of global variables_ that we're
addressing here.

And, since I'm being downvoted for technical discussion (presumably by you
guys or your friends, because I've never seen anything like this to comments
like mine on hacker news), I'm going to respond personally:

Your need to find (and listen to) an advisor who has a significant stake in
the ObjC space and more experience with API design than you have. You appear
to be approaching your API from a Rails-centric perspective, not one rooted in
Objective-C application development experience, and certainly not one rooted
in the experience of architecting large shipping desktop/mobile applications.

Then again, maybe your target audience are just small throw-away apps, in
which case your API is probably fine -- just about any API would be.

------
Nemisis7654
I am assuming these features are being worked on for Android as well. Any time
frame as to when they will be added to the Android API?

~~~
csmajorfive
Yep - coming in the next few weeks!

------
nubela
I don't get this Parse thing, why would I want another dependency in my
backend for my apps? Can someone explain?

~~~
lacker
In many cases, using Parse means you don't have to run your own backend
servers at all.

Even if you use Parse in conjunction with your own backend, it can be
convenient to add new functionality without having to touch any backend code.

------
TruthElixirX
Facebook authentication is so tiring. I wish people would knock it off. I have
to avoid registering at sites now because they insist on using Facebook.

I realize this isn't mandatory at this time though.

