安卓链接正常显示,ios#符被转义%23导致链接访问404

原因分析:

url中含有特殊字符 中文未编码 都有可能导致URL转换失败,所以需要对url编码处理

如下:

Swift 复制代码
   guard let allowUrl = webUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {
      return
   }

后面发现当url中有#号时,会被误伤转义为%23,导致链接无法访问。

这表名.urlQueryAllowed并没有包含字符"#"。

也有提供API可以测试:

Swift 复制代码
.urlQueryAllowed.contains("#")

解决方案:

显而易见,只要将字符"#"加到.urlQueryAllowed即可解决这个问题。

CharacterSet提供了三个方法:

Swift 复制代码
取并集
/// Returns a union of the `CharacterSet` with another `CharacterSet`.
public func union(_ other: CharacterSet) -> CharacterSet

取交集
/// Returns an intersection of the `CharacterSet` with another `CharacterSet`.
public func intersection(_ other: CharacterSet) -> CharacterSet

取补集
/// Returns a `CharacterSet` created by removing elements in `other` from `self`.
public func subtracting(_ other: CharacterSet) -> CharacterSet

为CharacterSet增加一个新属性

Swift 复制代码
extension CharacterSet {
    static let allowedCharacters = urlQueryAllowed.union(.init(charactersIn: "#"))
}

上面的url编码方法改为

Swift 复制代码
   guard let allowUrl = webUrl.addingPercentEncoding(withAllowedCharacters: .allowedCharacters) else {
      return
   }

在编码过程中不对字符#操作即可解决。

寻根究底

.urlQueryAllowed中到底包含哪些字符?

以下是遍历NSCharacterSet字符集一种的实现方式。(摘自:URL详解以及iOS中URLencode和URLdecode

Swift 复制代码
NSString* characters(NSCharacterSet *set){
    NSMutableString *string = [NSMutableString string];
    for (UInt8 plane = 0; plane < 17; plane++) {
        if ([set hasMemberInPlane:plane]){
            UInt32 p0 = (UInt32)plane * 65535;
            UInt32 p1 = (UInt32)(plane + 1) * 65535;
            for (UInt32 i = p0; i < p1; i ++) {
                if([set longCharacterIsMember:i]){
                    [string appendFormat:@"%c",I];
                }
            }
        }
    }
    return string;
 }

原理:OC中的字符是Unicode字符集(Swift也是)Unicode共有17个扇区,每个扇区能表示65535个Unicode字符,用4个字节就可以表示任意Unicode码点,通过遍历Unicode字符集就可以找出NSCharacterSet包含的集合了;

hasMemberInPlane:判断当前字符是否在当前扇区。

longCharacterIsMember:当前字符在字符集中是否存在。

NSCharacterSet提供了标准字符集:部分字符集遍历结果如下:

URLUserAllowedCharacterSet

复制代码
!$&'()*+,-.0123456789;=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~

URLHostAllowedCharacterSet

复制代码
!$&'()*+,-.0123456789:;=ABCDEFGHIJKLMNOPQRSTUVWXYZ[]_abcdefghijklmnopqrstuvwxyz~

URLPathAllowedCharacterSet

复制代码
!$&'()*+,-./0123456789:=@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~

URLQueryAllowedCharacterSet

复制代码
!$&'()*+,-./0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~

URLPasswordAllowedCharacterSet

复制代码
!$&'()*+,-.0123456789;=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~

URLFragmentAllowedCharacterSet

复制代码
!$&'()*+,-./0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~
相关推荐
pop_xiaoli7 小时前
【iOS】dyld加载
macos·ios·objective-c·cocoa
LoyalToOrigin10 小时前
iOS 26 libass字幕渲染问题兼容解决实践
ios·ffmpeg·objective-c
2501_9159214310 小时前
穿越HTTPS迷雾:Wireshark中的TLS抓包秘诀与文件合并方法
网络协议·ios·小程序·https·uni-app·wireshark·iphone
懋学的前端攻城狮10 小时前
网络层架构演进:从回调地狱到声明式数据流
ios
白狐_79815 小时前
【深度拆解】2026年数字化学习流:iPad 主动式电容笔的技术底层与选型实测
学习·ios·ipad·电容笔
2501_9159184116 小时前
快蝎iOS开发IDE:免Xcode开发,支持Swift/Flutter项目
ide·vscode·ios·个人开发·xcode·swift·敏捷流程
空中海1 天前
第十二章:iOS高级系统能力与 UIKit 互操作
ios
songgeb1 天前
用 AI 降低 iOS 客户端 UI 自动化测试难度
ios·测试
我现在不喜欢coding1 天前
Swift 核心协议揭秘:从 Sequence 到 Collection,你离标准库设计者只差这一步
ios·swift
开心就好20251 天前
使用Edge和ADB进行Android Webview远程调试的完整教程
前端·ios