IOS问题H5获取相册权限

1.IOS中嵌入H5网页,上传图片,没有反应。安卓上传都没任何问题,网页也可以。

2.IOS原生代码中,长按图片弹出菜单。版本IOS12.5.7上(老旧的iphone6)可以正常弹出。

像IOS16.6.1(较新的iphone12)长按图片都没反应。

各位有解决方法嘛!ios开发语言 objective-c h5用的是uniapp

img

ios确实很麻烦,考虑用第三方插件来兼容呢

引用 皆我百晓生 小程序回复内容作答:
针对你提到的问题,我给出一些常见的解决方法:

iOS中H5上传图片没有反应:iOS中H5上传图片需要获取相册权限。你可以在uni-app的配置文件manifest.json中,配置需要使用的权限。示例代码如下:

{
  "uni-app": {
    "app-plus": {
      "ios": {
        "info": {
          "NSPhotoLibraryUsageDescription": "需要访问相册权限"
        }
      }
    }
  }
}

在以上示例中,我们添加了NSPhotoLibraryUsageDescription字段,用于申请相册权限。你可以根据实际情况修改描述文本。

iOS中长按图片没有反应:iOS的长按事件通常需要通过JavaScript和原生交互来实现。你可以通过uni-app的uni.showToast()或uni.showActionSheet()等方法,在H5中与原生交互,触发长按事件。示例代码如下:

// H5端代码
uni.showToast({
  title: '长按图片',
  duration: 2000,
  success: function() {
    // 调用原生代码
    uni.postMessage({
      action: 'longPressImage',
      imageUrl: '图片URL'
    });
  }
});

在原生的iOS代码中,监听来自H5的消息,并处理长按事件。示例代码如下:

#import <UIKit/UIKit.h>
#import <WebKit/WebKit.h>
 
@interface ViewController () <WKScriptMessageHandler>
@property (nonatomic, strong) WKWebView *webView;
@end
 
@implementation ViewController
 
- (void)viewDidLoad {
    [super viewDidLoad];
    
    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
    WKUserContentController *userContentController = [[WKUserContentController alloc] init];
    
    // 注册H5发送的消息类型
    [userContentController addScriptMessageHandler:self name:@"postMessage"];
    
    config.userContentController = userContentController;
    
    self.webView = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:config];
    [self.view addSubview:self.webView];
    
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"index" withExtension:@"html"];
    [self.webView loadRequest:[NSURLRequest requestWithURL:url]];
}
 
-  (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    if ([message.name isEqualToString:@"postMessage"] && [message.body isKindOfClass:[NSDictionary class]]) {
        NSDictionary *data = (NSDictionary *)message.body;
        
        NSString *action = data[@"action"];
        if ([action isEqualToString:@"longPressImage"]) {
            // 处理长按事件
            NSString *imageUrl = data[@"imageUrl"];
            
            // 执行你的逻辑
        }
    }
}
 
@end

以上代码演示了在iOS原生代码中,监听来自H5发送的消息,并处理长按图片的事件。

希望以上解决方法对你有帮助!

1.H5页面上的文件上传控件是正常的。有时候,HTML代码中可能存在错误,导致文件上传控件无法正常工作。你可以在H5代码中添加一个简单的文件上传控件来测试。如果你的H5页面中包含JavaScript代码来处理文件上传,确保没有错误。你可以在iOS Safari的开发者工具中查看控制台日志,以查找潜在的JavaScript错误。
代码示例

document.getElementById("fileInput").addEventListener("change", function (event) {
    var selectedFile = event.target.files[0];
    // 处理选择的文件,可以上传到服务器或进行其他操作
});


2.如果长按图片在较新的iOS版本上无法工作,但在较旧的iOS版本上正常,请确保你的代码在不同版本的iOS上进行测试,并考虑对不同版本的iOS进行适配。有些API或行为在不同iOS版本之间可能会有变化。用UILongPressGestureRecognizer来检测长按动作,确保手势识别器与目标视图关联并添加到视图上。
代码示例

// 导入头文件
#import <UIKit/UIGestureRecognizerSubclass.h>

// 创建长按手势识别器
UILongPressGestureRecognizer *longPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
longPressRecognizer.minimumPressDuration = 0.5; // 设置长按时长
[imageView addGestureRecognizer:longPressRecognizer]; // imageView是你的UIImageView

// 处理长按事件
- (void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer {
    if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
        // 长按事件发生时执行你的操作,例如显示菜单
        NSLog(@"长按图片");
        
        // 在这里可以弹出菜单或执行其他操作
    }
}


【相关推荐】




如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

#import <UIKit/UIKit.h>
#import <WebKit/WebKit.h>
@interface ViewController () <WKScriptMessageHandler>
@property (nonatomic, strong) WKWebView *webView;
@end
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
    WKUserContentController *userContentController = [[WKUserContentController alloc] init];
    // 注册H5发送的消息类型
    [userContentController addScriptMessageHandler:self name:@"postMessage"];
    config.userContentController = userContentController;
    self.webView = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:config];
    [self.view addSubview:self.webView];
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"index" withExtension:@"html"];
    [self.webView loadRequest:[NSURLRequest requestWithURL:url]];
}
-  (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    if ([message.name isEqualToString:@"postMessage"] && [message.body isKindOfClass:[NSDictionary class]]) {
        NSDictionary *data = (NSDictionary *)message.body;
        NSString *action = data[@"action"];
        if ([action isEqualToString:@"longPressImage"]) {
            // 处理长按事件
            NSString *imageUrl = data[@"imageUrl"];
            // 执行你的逻辑
        }
    }
}
@end

援引讯飞星火:
针对您的问题,我提供以下解决方法:

  1. 在iOS中嵌入H5网页上传图片没有反应的问题,可以尝试以下方法:

    • 确保您的H5网页代码正确无误,可以在其他设备上进行测试。
    • 检查您的iOS设备是否安装了最新版本的浏览器(如Safari)。
    • 检查您的iOS设备是否有权限访问相册。您可以在设置中找到应用程序权限,确保允许访问相册。
    • 尝试使用不同的浏览器进行测试,以确定问题是否与特定浏览器有关。
  2. 对于iOS原生代码中长按图片弹出菜单无法正常弹出的问题,可以尝试以下方法:

    • 确保您的iOS设备运行的是最新版本的iOS操作系统。
    • 检查您的代码是否正确处理了长按事件和弹出菜单的逻辑。
    • 确保您的应用程序具有访问相册的权限。您可以在Xcode中的应用程序设置中检查并添加相应的权限。
    • 如果问题仍然存在,您可以尝试使用第三方库或框架来处理图片的长按事件和弹出菜单。

请注意,以上建议仅供参考,具体解决方法可能因实际情况而异。如果问题仍然存在,建议您查阅相关文档或向开发者社区寻求帮助。

iOS与H5交互 询问相机、相册权限的问题
可以参考下

如果你在iOS设备上的嵌入式H5网页中遇到图片上传问题,而在安卓和其他平台上都正常,这可能是由于iOS的权限、兼容性或特定的浏览器行为造成的。

下面是一些建议和可能的解决方案:

  1. 检查<input>标签:确保你的<input>标签具有正确的属性。例如:

    <input type="file" accept="image/*">
    
  2. 权限问题:iOS对相机和相册的访问权限非常严格。确保在请求访问相册或相机之前已获取适当的权限。

  3. 事件冒泡问题:在某些情况下,iOS上的触摸事件可能不会正确地冒泡。尝试使用cursor: pointer;CSS属性或JavaScript添加事件监听器来解决此问题。

  4. 使用第三方库:考虑使用经过验证的第三方库,如blueimp's jQuery-File-Upload,以确保兼容性。

  5. iOS Safari的限制:确保测试的浏览器和iOS版本支持你的上传方法。例如,某些iOS版本的Safari可能不支持某些文件API功能。

  6. 检查JavaScript控制台错误:使用Safari的开发者工具检查嵌入式网页的控制台错误,以确定是否有任何阻止上传的JavaScript错误。

  7. MIME类型限制:确保你的上传逻辑支持iOS设备上传的图片的MIME类型。例如,HEIC格式是iOS的默认图片格式,但不是所有后端服务都支持它。

  8. 尝试其他方法:使用XHR2 (XMLHttpRequest 2) 或FormData API进行异步文件上传。

  9. 更新或回退:尝试将iOS设备更新到最新版本或回退到之前的版本,查看问题是否仍然存在。

  10. 求助:如果以上方法都无法解决问题,考虑在开发者社区,如Stack Overflow,发布问题以获得更具体的帮助。

记住,由于iOS设备和浏览器的多样性,建议在多种设备和iOS版本上进行测试,以确保覆盖尽可能多的使用场景。

结合GPT给出回答如下请题主参考

  1. H5获取相册权限

在iOS的Safari浏览器中,在H5中调用相册功能需要用户允许浏览器访问相册。可以使用以下代码请求用户授权:

// 检查是否授权
function checkAuth() {
  if (window.navigator && window.navigator.mediaDevices && window.navigator.mediaDevices.getUserMedia) {
    return window.navigator.permissions.query({ name: 'camera' })
      .then(function(permissionStatus) {
        return permissionStatus.state;
       });
  } else {
    return Promise.reject('getUserMedia not supported');
  }
}

// 请求授权
function requestAuth() {
  if (window.navigator && window.navigator.mediaDevices && window.navigator.mediaDevices.getUserMedia) {
    return window.navigator.mediaDevices.getUserMedia({ video: true, audio: true })
      .then(function(stream) {
        stream.getTracks().forEach(function(track) {
          track.stop();
        });
        return 'granted';
      })
      .catch(function(error) {
        return 'denied';
      });
  } else {
    return Promise.reject('getUserMedia not supported');
  }
}

// 在需要获取权限的地方调用
checkAuth().then(function(state) {
  if (state == 'granted') {
    // 已授权
  } else {
    // 请求授权
    requestAuth().then(function(state) {
      if (state == 'granted') {
        // 授权成功
      } else {
        // 授权失败
      }
    });
  }
});

代码说明:

首先通过window.navigator.permissions.query({ name: 'camera' })检查是否已授权,返回一个状态对象permissionStatus,使用then方法获取状态的state属性。如果stategranted,表示已授权;如果stateprompt,表示需要请求授权;如果statedenied,表示拒绝授权。

如果需要请求授权,可以调用window.navigator.mediaDevices.getUserMedia({ video: true, audio: true }),该方法返回一个Promise对象,成功时返回一个MediaStream对象,失败时返回一个错误对象。由于我们不需要使用摄像头和麦克风,所以可以将参数设置为{ video: true, audio: true },并在成功回调中停止所有轨道。

  1. 原生代码中长按图片弹出菜单

可以使用UILongPressGestureRecognizer来实现长按图片弹出菜单的效果。代码示例如下:

// 在UIView中添加手势识别器
UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPressGesture:)];
imageView.userInteractionEnabled = YES;
[imageView addGestureRecognizer:longPressGesture];

// 手势处理方法
- (void)handleLongPressGesture:(UILongPressGestureRecognizer *)gesture {
  if (gesture.state == UIGestureRecognizerStateBegan) {
    // 创建菜单
    UIMenuItem *saveImageItem = [[UIMenuItem alloc] initWithTitle:@"保存图片" action:@selector(saveImage:)];
    UIMenuController *menuController = [UIMenuController sharedMenuController];
    [menuController setMenuItems:@[saveImageItem]];
    [menuController setTargetRect:gesture.view.frame inView:gesture.view.superview];
    [menuController setMenuVisible:YES animated:YES];
  }
}

// 保存图片方法
- (void)saveImage:(UIMenuItem *)menuItem {
    UIImageWriteToSavedPhotosAlbum(imageView.image, self, @selector(imageSavedToPhotosAlbum:didFinishSavingWithError:contextInfo:), nil);
}

// 保存图片到相册回调方法
- (void)imageSavedToPhotosAlbum:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
    if (error) {
        NSLog(@"保存图片到相册失败:%@", error.localizedDescription);
    } else {
        NSLog(@"保存图片到相册成功");
    }
}

代码说明:

首先在UIImageView中添加UILongPressGestureRecognizer手势识别器,设置目标响应方法handleLongPressGesture:。在该方法中判断手势状态是否为UIGestureRecognizerStateBegan,如果是则创建菜单。可以通过UIMenuItem创建菜单项,然后将菜单项数组赋值给UIMenuController的menuItems属性,设置菜单显示的目标矩形和父视图,最后调用setMenuVisible方法来显示菜单。

当用户选择菜单项时,会触发目标方法saveImage:。在该方法中可以将图片保存到相册,使用UIImageWriteToSavedPhotosAlbum方法即可,成功时会回调方法imageSavedToPhotosAlbum:didFinishSavingWithError:contextInfo:,失败时会将错误信息传递给该方法的error参数。

需要注意的是,为了保证UI更新在主线程进行,需要给UIMenuController的方法调用添加dispatch_async(dispatch_get_main_queue(), ^{})。另外,需要在项目的Info.plist文件中添加一个NSPhotoLibraryUsageDescription键,值为描述用户需要授予访问相册的原因的字符串。