Essentially, the problem is a common one for asymmetric cryptography: in order to send an encrypted message to someone, you need their public key (they then use their private key to decrypt the message on their end). But how do you find out what someone’s public key is? And how do you know the key you’ve received is the real one? At some point along the line, you end up trusting that malicious third parties haven’t spoofed you into accepting their public key, rather than that of your intended recipient. It’s a hard problem to solve, and is the reason why crypto enthusiasts hold IRL meetups to swap public keys face-to-face. Obviously, this isn’t really viable for a mass-market messaging system like iMessage, so Apple acts as a directory from which people can look up public keys for iMessage users. By substituting a their own key, Apple could theoretically read the messages.
One thing that could mitigate risk somewhat would be for the client to warn users when a public key of someone they’re messaging changes suddenly, although it also risks causing irritation and undue alarm when, say someone gets a new phone. Maybe a way to transfer private keys, or sign an authorisation of a new one, could work (perhaps using ad-hoc networking – touch the phones together to authorise a new device). It would inevitably involve a level of user experience trade-off, though.