facebook / facebook-ios-sdk

Used to integrate the Facebook Platform with your iOS & tvOS apps.
https://developers.facebook.com/docs/ios
Other
7.8k stars 3.56k forks source link

Shouldn't imageURL(forMode: , size: ) be available even in a limited login? #2410

Open ChaminLee opened 7 months ago

ChaminLee commented 7 months ago

Checklist before submitting a feature request

Goals

I want to get a large profile image using imageURL(forMode: , size: ) at loginTracking is .limited (using limited login)

Expected results

I want to get a large profile image using imageURL(forMode: , size: ), even when loginTracking is .limited.

I followed the documentation and implemented limited login. but imageURL(forMode: , size: ) returns the following error and does not provide valid image url even though loginTracking is .limited

{
   "error": {
      "message": "Invalid OAuth access token - Cannot parse access token",
      "type": "OAuthException",
      "code": 190,
      "fbtrace_id": "-"
   }
}

Looking at Profile+ImageURL's implementation, I see that it uses an "access token", but when login tracking is .limited, the method cannot be used because the access token is nil. Therefore, I cannot get a large profile image on limited login.

  1. is this intended behavior?
  2. is this limitation because profile images should not be used on limited login?
  3. should I just use the imageURL to get the profile image for limited login?
    • The documentation used a property called Profile.current?.linkURL, but that property returns null even if there is actually a registered profile when limited login

If this is an error, I was wondering if it could be fixed soon. Or if not, I'd like to know if there is a completely different approach.

Code samples & details

@objc(imageURLForPictureMode:size:)
  public func imageURL(forMode pictureMode: PictureMode, size: CGSize) -> URL? {
    Self.getImageURL(profileID: userID, pictureMode: pictureMode, size: size)
  }

static func getImageURL(
    profileID: String,
    pictureMode: PictureMode,
    size: CGSize
  ) -> URL? {
    guard let dependencies = try? Self.getDependencies() else { return nil }

    var queryItems: [ImageURL.QueryItemName: String] = [
      .pictureMode: ImageURL.PictureMode(mode: pictureMode).rawValue,
      .width: String(Int(size.width)),
      .height: String(Int(size.height)),
    ]

    if let token = dependencies.accessTokenProvider.current {   /// This is where the lack of a token becomes an issue.
      queryItems[.accessToken] = token.tokenString
    } else if let token = dependencies.settings.clientToken {
      queryItems[.accessToken] = token
    } else {
      print(
        """
        As of Graph API v8.0, profile images may not be retrieved without a token. This can be the current access \
        token from logging in with Facebook or it can be set via the plist or in code. Providing neither will cause \
        this call to return a silhouette image.
        """
      )
    }

    let stringlyKeyedItems = queryItems.reduce(into: [String: String]()) { values, item in
      values[item.key.rawValue] = item.value
    }

    var hostPrefix = ImageURL.hostPrefix
    if _DomainHandler.sharedInstance().isDomainHandlingEnabled() {
      let domainConfig = _DomainConfigurationManager.sharedInstance().cachedDomainConfiguration()
      if let domainHandlingHostPrefix =
        domainConfig.domainInfo?["default_config"]?["default_alternative_domain_prefix"] as? String {
        hostPrefix = domainHandlingHostPrefix
      } else {
        hostPrefix = ImageURL.defaultDomainHandlingHostPrefix
      }
    }
    return try? dependencies.urlHoster.facebookURL(
      hostPrefix: hostPrefix,
      path: "\(profileID)/\(ImageURL.path)",
      queryParameters: stringlyKeyedItems
    )
  }