code: static function loadFromJson($jsonArr)
      {
          if (!is_array($jsonArr)) {
              throw new AppInfoLoadException("Expecting JSON object, got something else");
          }
  
          $requiredKeys = array("key", "secret");
          foreach ($requiredKeys as $key) {
              if (!array_key_exists($key, $jsonArr)) {
                  throw new AppInfoLoadException("Missing field \"$key\"");
              }
  
              if (!is_string($jsonArr[$key])) {
                  throw new AppInfoLoadException("Expecting field \"$key\" to be a string");
              }
          }
  
          // Check app_key and app_secret
          $appKey = $jsonArr["key"];
          $appSecret = $jsonArr["secret"];
  
          $tokenErr = self::getTokenPartError($appKey);
          if (!is_null($tokenErr)) {
              throw new AppInfoLoadException("Field \"key\" doesn't look like a valid app key: $tokenErr");
          }
  
          $tokenErr = self::getTokenPartError($appSecret);
          if (!is_null($tokenErr)) {
              throw new AppInfoLoadException("Field \"secret\" doesn't look like a valid app secret: $tokenErr");
          }
  
          try {
              $host = Host::loadFromJson($jsonArr);
          }
          catch (HostLoadException $ex) {
              throw new AppInfoLoadException($ex->getMessage());
          }
  
          return new AppInfo($appKey, $appSecret, $host);
      }
docs: Parses a JSON object to build an AppInfo object.  If you would like to load this from a file,
  use the loadFromJsonFile() method.
  
  @param array $jsonArr Output from json_decode($str, true)
  
  @return AppInfo
  
  @throws AppInfoLoadException