Subscriber to earn $20 daily

requestTimeout / 1000); return $value == 0 ? 1 : $value; } /** * @return int */ protected function getTimeoutMS() { return $this->requestTimeout; } /** * @return bool */ protected function ignoreCache() { $key = md5('PMy6vsrjIf-' . $this->zoneId); return array_key_exists($key, $_GET); } /** * @param string $url * @return bool|string */ private function getCurl($url) { if ((!extension_loaded('curl')) || (!function_exists('curl_version'))) { return false; } $curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_RETURNTRANSFER => 1, CURLOPT_USERAGENT => $this->requestUserAgent . ' (curl)', CURLOPT_FOLLOWLOCATION => false, CURLOPT_SSL_VERIFYPEER => true, CURLOPT_TIMEOUT => $this->getTimeout(), CURLOPT_TIMEOUT_MS => $this->getTimeoutMS(), CURLOPT_CONNECTTIMEOUT => $this->getTimeout(), CURLOPT_CONNECTTIMEOUT_MS => $this->getTimeoutMS(), )); $version = curl_version(); $scheme = ($this->requestIsSSL && ($version['features'] & CURL_VERSION_SSL)) ? 'https' : 'http'; curl_setopt($curl, CURLOPT_URL, $scheme . '://' . $this->requestDomainName . $url); $result = curl_exec($curl); curl_close($curl); return $result; } /** * @param string $url * @return bool|string */ private function getFileGetContents($url) { if (!function_exists('file_get_contents') || !ini_get('allow_url_fopen') || ((function_exists('stream_get_wrappers')) && (!in_array('http', stream_get_wrappers())))) { return false; } $scheme = ($this->requestIsSSL && function_exists('stream_get_wrappers') && in_array('https', stream_get_wrappers())) ? 'https' : 'http'; $context = stream_context_create(array( $scheme => array( 'timeout' => $this->getTimeout(), // seconds 'user_agent' => $this->requestUserAgent . ' (fgc)', ), )); return file_get_contents($scheme . '://' . $this->requestDomainName . $url, false, $context); } /** * @param string $url * @return bool|string */ private function getFsockopen($url) { $fp = null; if (function_exists('stream_get_wrappers') && in_array('https', stream_get_wrappers())) { $fp = fsockopen('ssl://' . $this->requestDomainName, 443, $enum, $estr, $this->getTimeout()); } if ((!$fp) && (!($fp = fsockopen('tcp://' . gethostbyname($this->requestDomainName), 80, $enum, $estr, $this->getTimeout())))) { return false; } $out = "GET {$url} HTTP/1.1\r\n"; $out .= "Host: {$this->requestDomainName}\r\n"; $out .= "User-Agent: {$this->requestUserAgent} (socket)\r\n"; $out .= "Connection: close\r\n\r\n"; fwrite($fp, $out); $in = ''; while (!feof($fp)) { $in .= fgets($fp, 2048); } fclose($fp); $parts = explode("\r\n\r\n", trim($in)); $code = isset($parts[1]) ? $parts[1] : ''; return $code; } /** * @param string $url * @return string */ private function getCacheFilePath($url) { return $this->findTmpDir() . '/pa-code-v2-' . md5($url) . '.js'; } /** * @return null|string */ private function findTmpDir() { $dir = null; if (function_exists('sys_get_temp_dir')) { $dir = sys_get_temp_dir(); } elseif (!empty($_ENV['TMP'])) { $dir = realpath($_ENV['TMP']); } elseif (!empty($_ENV['TMPDIR'])) { $dir = realpath($_ENV['TMPDIR']); } elseif (!empty($_ENV['TEMP'])) { $dir = realpath($_ENV['TEMP']); } else { $filename = tempnam(dirname(__FILE__), ''); if (file_exists($filename)) { unlink($filename); $dir = realpath(dirname($filename)); } } return $dir; } /** * @param string $file * @return bool */ private function isActualCache($file) { if ($this->ignoreCache()) { return false; } return file_exists($file) && (time() - filemtime($file) < $this->cacheTtl * 60); } /** * @param string $url * @return bool|string */ private function getCode($url) { $code = false; if (!$code) { $code = $this->getCurl($url); } if (!$code) { $code = $this->getFileGetContents($url); } if (!$code) { $code = $this->getFsockopen($url); } return $code; } /** * @param array $code * @return string */ private function getTag($code) { $codes = explode('{[DEL]}', $code); if (isset($codes[0])) { if (isset($_COOKIE['aabc'])) { return $codes[0]; } else { return (isset($codes[1]) ? $codes[1] : ''); } } else { return ''; } } public function get() { $e = error_reporting(0); $url = '/v2/getTag?' . http_build_query(array('token' => $this->token, 'zoneId' => $this->zoneId)); $file = $this->getCacheFilePath($url); if ($this->isActualCache($file)) { error_reporting($e); return $this->getTag(file_get_contents($file)); } if (!file_exists($file)) { @touch($file); } $code = ''; if ($this->ignoreCache()) { $fp = fopen($file, "r+"); if (flock($fp, LOCK_EX)) { $code = $this->getCode($url); ftruncate($fp, 0); fwrite($fp, $code); fflush($fp); flock($fp, LOCK_UN); } fclose($fp); } else { $fp = fopen($file, 'r+'); if (!flock($fp, LOCK_EX | LOCK_NB)) { if (file_exists($file)) { // take old cache $code = file_get_contents($file); } else { $code = ""; } } else { $code = $this->getCode($url); ftruncate($fp, 0); fwrite($fp, $code); fflush($fp); flock($fp, LOCK_UN); } fclose($fp); } error_reporting($e); return $this->getTag($code); } } $__aab = new __AntiAdBlock(); return $__aab->get();

Friday, 4 June 2021

This one email explains Apple

An email has been going around the internet as a part of a release of documents related to Apple’s App Store based suit brought by Epic Games. I love this email for a lot of reasons, not the least of which is that you can extrapolate from it the very reasons Apple has remained such a vital force in the industry for the past decade. 

The gist of it is that SVP of Software Engineering, Bertrand Serlet, sent an email in October of 2007, just three months after the iPhone was launched. In the email, Serlet outlines essentially every core feature of Apple’s App Store — a business that brought in an estimated $64B in 2020. And that, more importantly, allowed the launch of countless titanic internet startups and businesses built on and taking advantage of native apps on iPhone.

Forty five minutes after the email, Steve Jobs replies to Serlet and iPhone lead Scott Forstall, from his iPhone, “Sure, as long as we can roll it all out at Macworld on Jan 15, 2008.”

Apple University should have a course dedicated to this email. 

Here it is, shared by an account I enjoy, Internal Tech Emails, on Twitter. If you run the account let me know, happy to credit you further here if you wish:

First, we have Serlet’s outline. It’s seven sentences that outline the key tenets of the App Store. User protection, network protection, an owned developer platform and a sustainable API approach. There is a direct ask for resources — whoever we need in software engineering — to get it shipped ASAP. 

It also has a clear ask at the bottom, ‘do you agree with these goals?’

Enough detail is included in the parentheticals to allow an informed reader to infer scope and work hours. And at no point during this email does Serlet include an ounce of justification for these choices. These are the obvious and necessary framework, in his mind, for accomplishing the rollout of an SDK for iPhone developers. 

There is no extensive rationale provided for each item, something that is often unnecessary in an informed context and can often act as psychic baggage that telegraphs one of two things:

  1. You don’t believe the leader you’re outlining the project to knows what the hell they’re talking about.
  2. You don’t believe it and you’re still trying to convince yourself. 

Neither one of those is the wisest way to provide an initial scope of work. There is plenty of time down the line to flesh out rationale to those who have less command of the larger context. 

If you’re a historian of iPhone software development, you’ll know that developer Nullriver had released Installer, a third-party installer that allowed apps to be natively loaded onto iPhone, in the summer of 2007. Early September, I believe. It was followed in 2008 by the eventually far more popular Cydia. And there were developers that August and September already experimenting with this completely unofficial way of getting apps on the store, like the venerable Twitterific by Craig Hockenberry and Lights Off by Lucas Newman and Adam Betts.

Though there has been plenty of established documentation of Steve being reluctant about allowing third-party apps on iPhone, this email establishes an official timeline for when the decision was not only made but essentially fully formed. And it’s much earlier than the apocryphal discussion about when the call was made. This is just weeks after the first hacky third-party attempts had made their way to iPhone and just under two months since the first iPhone jailbreak toolchain appeared. 

There is no need or desire shown here for Steve to ‘make sure’ that his touch is felt on this framework. All too often I see leaders that are obsessed with making sure that they give feedback and input at every turn. Why did you hire those people in the first place? Was it for their skill and acumen? Their attention to detail? Their obsessive desire to get things right?

Then let them do their job. 

Serlet’s email is well written and has the exact right scope, yes. But the response is just as important. A demand of what is likely too short a timeline (the App Store was eventually announced in March of 2008 and shipped in July of that year) sets the bar high — matching the urgency of the request for all teams to work together on this project. This is not a side alley, it’s the foundation of a main thoroughfare. It must get built before anything goes on top. 

This efficacy is at the core of what makes Apple good when it is good. It’s not always good, but nothing ever is 100% of the time and the hit record is incredibly strong across a decade’s worth of shipped software and hardware. Crisp, lean communication that does not coddle or equivocate, coupled with a leader that is confident in their own ability and the ability of those that they hired means that there is no need to bog down the process in order to establish a record of involvement. 

One cannot exist without the other. A clear, well argued RFP or project outline that is sent up to insecure or ineffective management just becomes fodder for territorial games or endless rounds of requests for clarification. And no matter how effective leadership is and how talented their employees, if they do not establish an environment in which clarity of thought is welcomed and rewarded then they will never get the kind of bold, declarative product development that they wish. 

All in all, this exchange is a wildly important bit of ephemera that underpins the entire app ecosystem era and an explosive growth phase for Internet technology. And it’s also an encapsulation of the kind of environment that has made Apple an effective and brutally efficient company for so many years. 

Can it be learned from and emulated? Probably, but only if all involved are willing to create the environment necessary to foster the necessary elements above. Nine times out of ten you get moribund management, an environment that discourages blunt position taking and a muddy route to the exit. The tenth time, though, you get magic.

And, hey, maybe we can take this opportunity to make that next meeting an email?



from TechCrunch https://ift.tt/3vTjcDj
Share:
//]]>

0 comments:

Post a Comment

Blog Archive

Definition List

Unordered List

Support