吾八哥博客

您现在的位置是:首页 > 码农手记 > Delphi > 正文

Delphi

Firemonkey开发APP实现分享功能

吾八哥2017-11-05Delphi4590

前言

大家开发APP的时候,都希望内置一个分享功能,方便用户把APP分享给自己的朋友,那么在使用Firemonkey开发App的过程中,如何实现分享的功能呢?

实现方法

借助万能的搜索引擎查阅了一下,在XCode里是可以使用UIActivityViewController组件的,我们Delphi里也可以进行类似UIActivityViewController组件的调用,那么希望自己按照接口的规则去填充一个NSArray的数组,这个可以根据XCode相关的代码翻译过来即可。这里要告诉大家的是我们Delphi里已经对这个功能进行了封装,它封装的类名叫TShowShareSheetAction,是内置在TActionList组件里的。不过遗憾的是TShowShareSheetAction有点小问题,在分享URL的时候会出现无标题的情况,吾八哥我将这个做了个简单的修正,让我们分享的时候可以自己指定这个标题。

代码修正所在的单元FMX.MediaLibrary.IOS.pas,代码如下:

procedure TShareService.Share(const AControl: TControl; const AText: string; const ABitmap: TBitmap);
  procedure ShowForPhone;
  var
    Window: UIWindow;
  begin
    Window := SharedApplication.keyWindow;
    if (Window <> nil) and (Window.rootViewController <> nil) then
      Window.rootViewController.presentModalViewController(FActivityViewController, True);
  end;
  procedure ShowForPad;
  var
    Window: UIWindow;
    PopoverRect: CGRect;
    AbsolutePos: TPointF;
  begin
    Window := SharedApplication.keyWindow;
    if AControl <> nil then
    begin
      AbsolutePos := AControl.LocalToAbsolute(PointF(0, 0));
      if AControl.Scene <> nil then
        AbsolutePos := AControl.Scene.LocalToScreen(AbsolutePos);
      PopoverRect := CGRectMake(AbsolutePos.X, AbsolutePos.Y, AControl.Width, AControl.Height);
    end
    else
      PopoverRect := CGRectMake(0, 0, 0, 0);
    FPopoverController := TUIPopoverController.Alloc;
    FPopoverController.initWithContentViewController(FActivityViewController);
    FPopoverController.presentPopoverFromRect(PopoverRect, Window.rootViewController.View, UIPopoverArrowDirectionAny, True);
  end;
  procedure ShowActionsSheet;
  begin
    if IsPad then
      ShowForPad
    else
      ShowForPhone;
  end;
var
  OCImage: UIImage;
  TextList: TStringList;
begin
  Assert((ABitmap <> nil) or not AText.IsEmpty);
  FActivityItems.removeAllObjects;
  { TODO -o5bug : 修正分享无标题的问题 }
  if not AText.IsEmpty then
  begin
    TextList := TStringList.Create;
    try
      TextList.CommaText := AText;
      case TextList.Count of
        1:
          FActivityItems.addObject((StrToNSStr(AText) as ILocalObject).GetObjectID);
        2:
          begin
            FActivityItems.addObject((StrToNSStr(TextList[0]) as ILocalObject).GetObjectID);
            FActivityItems.addObject((StrToNSUrl(TextList[1]) as ILocalObject).GetObjectID);
          end;
      end;
    finally
      TextList.Free;
    end;
  end;
  if (ABitmap <> nil) and not ABitmap.IsEmpty then
  begin
    OCImage := BitmapToUIImage(ABitmap);
    FActivityItems.addObject((OCImage as ILocalObject).GetObjectID);
  end;
  try
    if FActivityItems.count > 0 then
    begin
      ReleaseOldSharingController;
      FActivityViewController := TUIActivityViewController.alloc;
      FActivityViewController.initWithActivityItems(FActivityItems , nil);
      ShowActionsSheet;
    end;
  finally
    if OCImage <> nil then
      OCImage.release;
  end;
end;

拷贝一份FMX.MediaLibrary.IOS.pas然后做上述改动后,放在工程代码文件夹里即可并且加到library path里即可,外部传参的时候使用换行符进行隔开,如下:

var 
  FShareAction: TShowShareSheetAction;
procedure TMaster.ShareURL(const AURL: string);
begin
  FShareAction.TextMessage := '史上最安全的密码管理工具!无广告,无需联网!' + #13#10 + 'http://www.uumima.com/';
  FShareAction.Bitmap.Assign(ImgLogo.Bitmap);
  FShareAction.ExecuteTarget(Self);
end;

效果截图:

QQ图片20171112224955-169x300.png

注:开发环境Delphi10.2.1