iOS 13 适配 适配详解 适配要点 最全 持续补充完善

iOS 13适配 适配指南

推送修改

原本可以直接将 NSData 类型的 deviceToken 转换成 NSString 字符串,然后替换掉多余的符号即可:

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    NSString *token = [deviceToken description];
    for (NSString *symbol in @[@" ", @"<", @">", @"-"]) {
        token = [token stringByReplacingOccurrencesOfString:symbol withString:@""];
    }
    NSLog(@"deviceToken:%@", token);
}
复制代码

在 iOS 13 中,这种方法已经失效,NSData类型的 deviceToken 转换成的字符串变成了:

{length = 32, bytes = 0xd7f9fe34 69be14d1 fa51be22 329ac80d ... 5ad13017 b8ad0736 } 
复制代码

解决方案

需要进行一次数据格式处理,参考友盟的做法,可以适配新旧系统,获取方式如下:

#include <arpa/inet.h>
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    if (![deviceToken isKindOfClass:[NSData class]]) return;
    const unsigned *tokenBytes = [deviceToken bytes];
    NSString *hexToken = [NSString stringWithFormat:@"%08x%08x%08x%08x%08x%08x%08x%08x",
                          ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),
                          ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),
                          ntohl(tokenBytes[6]), ntohl(tokenBytes[7])];
    NSLog(@"deviceToken:%@", hexToken);
}
复制代码

Xcode11 提交IAP包到开发者后台不展示构建版本


如果在升级Xcode11后,提交IAP包到开发者却长时间没有展示构建版本,去翻阅对应的邮箱邮件可能会有如下邮件:

**ITMS-90683: Missing Purpose String in Info.plist** - Your app's code references one or more APIs that access sensitive user data. The app's Info.plist file should contain a NSBluetoothAlwaysUsageDescription key with a user-facing purpose string explaining clearly and completely why your app needs the data. Starting Spring 2019, all apps submitted to the App Store that access user data are required to include a purpose string. If you're using external libraries or SDKs, they may reference APIs that require a purpose string. While your app might not use these APIs, a purpose string is still required. You can contact the developer of the library or SDK and request they release a version of their code that doesn't contain the APIs. Learn more ([https://developer.apple.com/documentation/uikit/core_app/protecting_the_user_s_privacy).](https://developer.apple.com/documentation/uikit/core_app/protecting_the_user_s_privacy). "https://developer.apple.com/documentation/uikit/core_app/protecting_the_user_s_privacy).")

After you’ve corrected the issues, you can use Xcode or Application Loader to upload a new binary to App Store Connect.

原因:

iOS13中新增蓝牙权限,需要添加对应权限申请说明。

解决方式:

target - info.plist下添加如下键值对:
Privacy - Bluetooth Always Usage Description : 使用用途

bluetooth.jpg

🈲止 KVC 对系统API私有属性的设置


下面方式对 UITextField 设置placeholder的颜色会产生崩溃

[_textField setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor”];

修改为:

[_textField setAttributedPlaceholder:<#(NSAttributedString * _Nullable)#>];

KVC获取状态栏(_statusBar)会导致崩溃

UIApplication *app = [UIApplication sharedApplication]; if ([[app valueForKeyPath:@"_statusBar"] isKindOfClass:NSClassFromString(@"UIStatusBar_Modern")]) {
NSArray *views = [[[[app valueForKeyPath:@"statusBar"] valueForKeyPath:@"statusBar"] valueForKeyPath:@"foregroundView"] subviews];

同理其他私有属性的读取也建议进行修改

UITextField leftView、rightView


问题:

  • 在设置leftView 左按钮时,如果使用的是UIImageView即会出现图片无法按照意图显示的问题。

解决:

  • UIImageVIew 包一层UIView再设置给leftView 、设置leftView或rightView不要使用约束布局

问题:

  • iOS13 rightView纯文本按钮可能无法正常显示,按钮长度变短。

解决:

  • 重新修改 - (CGRect)rightViewRectForBounds:(CGRect)bounds 大小

暗黑模式适配


具体适配的文章很多,这里就不做展开了。

着重说一点,如果没有需要支持的暗黑模式的需求,只需要在target 下的 info.plist中添加以下key & value

key:        User Interface Style
value :     Light

darkmode.jpg

其他

  • iOS 13 不再支持 UIApplicationExitsOnSuspend。需要更新应用以处理现代多任务处理。

iOS13 UIKit & API修改 & 一些细节


1. 新增部分Color,如下示例

@property (class, nonatomic, readonly) UIColor *systemGray2Color        API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *systemGray3Color        API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *systemGray4Color        API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *systemGray5Color        API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *systemGray6Color        API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);

#pragma mark Foreground colors

/* Foreground colors for static text and related elements.
 */
@property (class, nonatomic, readonly) UIColor *labelColor              API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
@property (class, nonatomic, readonly) UIColor *secondaryLabelColor     API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
@property (class, nonatomic, readonly) UIColor *tertiaryLabelColor      API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
@property (class, nonatomic, readonly) UIColor *quaternaryLabelColor    API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);

2. 根据系统设置 LightMode 和 DarkMode 状态取色

UIColor *backgroundColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * traitCollection) {
        self->_userInterfaceStyle = traitCollection.userInterfaceStyle;
        [weakSelf performSelector:@selector(traitCollectionChanged:) withObject:traitCollection];
        if (traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
            return [UIColor blueColor];
        }
        return [UIColor yellowColor];
    }];

3.UIActivityIndicatorView loading菊花修改

iOS13之前的三种样式:

  • UIActivityIndicatorViewStyleGray 灰色
  • UIActivityIndicatorViewStyleWhite 白色
  • UIActivityIndicatorViewStyleWhiteLarge 白色(大型)

iOS13废弃了以上三种样式,用以下两种样式代替:

  • UIActivityIndicatorViewStyleLarge(大型)
  • UIActivityIndicatorViewStyleMedium(中型)
    iOS13通过color属性设置颜色

4. statusBar修改

typedef NS_ENUM(NSInteger, UIStatusBarStyle) {
    UIStatusBarStyleDefault                                  = 0, // Automatically chooses light or dark content based on the user interface style
    UIStatusBarStyleLightContent     API_AVAILABLE(ios(7.0)) = 1, // Light content, for use on dark backgrounds
    UIStatusBarStyleDarkContent     API_AVAILABLE(ios(13.0)) = 3, // Dark content, for use on light backgrounds
    
    UIStatusBarStyleBlackTranslucent NS_ENUM_DEPRECATED_IOS(2_0, 7_0, "Use UIStatusBarStyleLightContent") = 1,
    UIStatusBarStyleBlackOpaque      NS_ENUM_DEPRECATED_IOS(2_0, 7_0, "Use UIStatusBarStyleLightContent") = 2,
} API_UNAVAILABLE(tvos);

在iOS13之前有两种状态,defaultlightContent
在iOS13 有三种状态,default, darkContentlightContent

darkContent 对应之前的 default
default 会根据情况自动选择 darkContentlightContent


5. [UIApplication sharedApplication].keyWindow API将被弃用

@property(nullable, nonatomic,readonly) UIWindow *keyWindow API_DEPRECATED("Should not be used for applications that support multiple scenes as it returns a key window across all connected scenes", ios(2.0, 13.0));

iOS13 UIApplication keyWindow被标记为API_DEPRECATED,

修改使用下方代码获取

[[[UIApplication sharedApplication] windows] objectAtIndex:0]

6. UISearchDisplayController彻底弃用,导致崩溃

在 iOS 8 之前,我们在 UITableView 上添加搜索框需要使用 UISearchBar + UISearchDisplayController 的组合方式。

在 iOS 8 之后,苹果就已经推出了 UISearchController 来代替这个组合方式。在 iOS 13 中,如果还继续使用 UISearchDisplayController会直接导致崩溃,崩溃信息如下:

Terminating app due to uncaught exception 'NSGenericException', reason: 'UISearchDisplayController is no longer supported when linking against this version of iOS. Please migrate your application to UISearchController.'

解决方法:使用UISearchController代替


7.MPMoviePlayerController 弃用

MPMoviePlayerController 在 iOS 9 开始被弃用,如果在 iOS 13 中继续使用的话会直接抛出异常:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'MPMoviePlayerController is no longer available. Use AVPlayerViewController in AVKit.'

解决办法:使用 AVPlayer 作为视频播放控件


8. 模态弹出默认样式改变 UIModalPresentationStyle

在 iOS 13,使用 presentViewController 方式打开视图,会跟导航栏有部分视觉差,如下图


UIModalPresentationStyle.jpeg

原因是:苹果将 UIViewController 的 modalPresentationStyle 属性的默认值改成了新加的一个枚举值 UIModalPresentationAutomatic,对于多数 UIViewController,此值会映射成 UIModalPresentationPageSheet。

解决办法: 可以在vcpresent之前设置modalPresentationStyle 为 UIModalPresentationFullScreen
另外,present的vc用户下拉可以dissmiss控制器,如果不想要这效果,可以这样设置

/*当该属性为 false 时,用户下拉可以 dismiss 控制器,为 true 时,下拉不可以 dismiss控制器*/
  xxVC.isModalInPresentation = true

还有一点需要注意,原来以UIModalPresentationFullScreen样式弹出页面,那么这个页面弹出 ViewController 会依次调viewWillDisappearviewDidDisappear。然后在这个页面被 dismiss 的时候,将他弹出的那个 ViewController 的 viewWillAppearviewDidAppear会被依次调用。然而使用默认的视差效果弹出页面,将他弹出的那个 ViewController 并不会调用这些方法,原先写在这四个函数中的代码以后都有可能会存在问题。


9.蓝牙权限相关修改

升级iOS13的用户很明显的体验就是,很多APP都会申请蓝牙权限,这与本次修改有关。

在 iOS 13 中,苹果将原来蓝牙申请权限用的 NSBluetoothPeripheralUsageDescription 字段,替换为 NSBluetoothAlwaysUsageDescription 字段。

For apps with a deployment target of iOS 13 and later, use NSBluetoothAlwaysUsageDescription instead.

10. iOS13彻底废弃UIWebview

iOS13 提交APP时,会提示UIWebview为过期API,会发送邮件提示你在下一次提交时将应用中UIWebView 的 api 移除。

Dear Developer,

We identified one or more issues with a recent delivery for your app, "xxx". Your delivery was successful, but you may wish to correct the following issues in your next delivery:

ITMS-90809: Deprecated API Usage - Apple will stop accepting submissions of apps that use UIWebView APIs . See [developer.apple.com/documentati…]([https://developer.apple.com/documentation/uikit/uiwebview](https://developer.apple.com/documentation/uikit/uiwebview)
) for more information.

After you’ve corrected the issues, you can use Xcode or Application Loader to upload a new binary to App Store Connect.

Best regards,

The App Store Team

暂时没有强制使用WKWebView,但是在iOS13开始UIWebView已是废弃的API,以后更高的版本中防止出现问题,应及时替换。


11. 第三方登录支持苹果登录 Sign In with Apple

在 iOS 13 中苹果推出一种在 App 和网站上便捷登录的方式: Sign In With Apple,这是 iOS 13 新增的功能,因此需要使用 Xcode 11 进行开发。

2020 年 4 月之前,Apple 平台 App 需接入 Sign in with Apple
苹果在上周更新了审核指南,加入 4.8 Sign in with Apple 一条,要求所有专门使用第三方登录的 App,都必须接入 Sign in with Apple。符合以下条件的App,可以不接入:

  • 使用自建账户和登录系统;
  • 要求用户使用现有的教育或企业账户登录的教育、企业或商业类应用;
  • 使用政府或行业支持的公民身份识别系统或电子 ID 来验证用户;
  • 应用特定于第三方服务,用户需要使用邮箱、社交媒体或其它第三方账户才能访问其内容的应用;

12. LaunchImage 修改(iOS 7.0–13.0)

UILaunchImages has been deprecated; use Xcode launch storyboards instead. For more information on how to construct and format your launch storyboard, seeLaunch Screen

从2020年4月开始,所有支持 iOS 13 的 App 必须提供 LaunchScreen.storyboard,否则将无法提交到 App Store 进行审批。


13. UISearchBar 黑线处理导致崩溃

iOS13之前为了处理搜索框的黑线问题,通常会遍历 searchBar 的 subViews,找到并删除 UISearchBarBackground。

修改为:

for (UIView *view in _searchBar.subviews.lastObject.subviews) {
    if ([view isKindOfClass:NSClassFromString(@"UISearchBarBackground")]) {
        view.layer.contents = nil;
        break;
    }
} 

设置 UISearchBarBackground 的 layer.contents 为 nil。


14.状态栏获取方法

UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];

15. TabBar红点偏移处理

如果之前有通过TabBar上图片位置来设置红点位置,在iOS13上会发现显示位置都在最左边。

遍历UITabBarButton的subViews,只有在TabBar选中状态下才能取到UITabBarSwappableImageView。

解决办法:通过UITabBarButton的位置来设置红点的frame


16. UIScrollView 滚动条异常偏移

添加以下代码


#ifdef __IPHONE_13_0
   if (@available(iOS 13.0, *)) {
       self.automaticallyAdjustsScrollIndicatorInsets = NO;
   }
#endif


17. UINavigationBar 设置按钮边距导致崩溃

从 iOS 11 开始,UINavigationBar 使用了自动布局,左右两边的按钮到屏幕之间会有 16 或 20 的边距。

为了避免点击到间距的空白处没有响应,通常做法是:定义一个 UINavigationBar 子类,重写 layoutSubviews 方法,在此方法里遍历 subviews 获取 _UINavigationBarContentView,并将其 layoutMargins 设置为 UIEdgeInsetsZero

- (void)layoutSubviews {
    [super layoutSubviews];

    for (UIView *subview in self.subviews) {
        if ([NSStringFromClass([subview class]) containsString:@"_UINavigationBarContentView"]) {
            subview.layoutMargins = UIEdgeInsetsZero;
            break;
        }
    }
}
复制代码

然而,这种做法在 iOS 13 中会导致崩溃,崩溃信息如下:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Client error attempting to change layout margins of a private view'
复制代码

解决方案

使用设置 frame 的方式,让 _UINavigationBarContentView 向两边伸展,从而抵消两边的边距。

- (void)layoutSubviews {
    [super layoutSubviews];

    for (UIView *subview in self.subviews) {
        if ([NSStringFromClass([subview class]) containsString:@"_UINavigationBarContentView"]) {
            if ([UIDevice currentDevice].systemVersion.floatValue >= 13.0) {
                UIEdgeInsets margins = subview.layoutMargins;
                subview.frame = CGRectMake(-margins.left, -margins.top, margins.left + margins.right + subview.frame.size.width, margins.top + margins.bottom + subview.frame.size.height);
            } else {
                subview.layoutMargins = UIEdgeInsetsZero;
            }
            break;
        }
    }
}

18.UISegmentedControl 默认样式改变

默认样式变为白底黑字,如果设置修改过颜色的话,页面需要修改。

原本设置选中颜色的 tintColor 已经失效,新增了 selectedSegmentTintColor属性用以修改选中的颜色。

转载部分 (以下转载自知识小集)

UIKit

  • 当单元格突出显示或选中时,UITableViewCell 类不再更改 contentView及其任何子视图的 backgroundColoropaque 属性。如果要在 contentView 内部(包括)内容的任何子视图上设置不透明的 backgroundColor,则单元格突出显示或选中时的外观可能会受到影响。解决子视图任何问题的最简单方法是确保将 backgroundColor 设置为 nil 或 clearColor,并且设置它们的 opaque 属性为 false。但是,如果需要,您可以重写 setHighlighted:animated:setSelected:animated: 方法,以便在移动到突出显示的状态和选定状态时手动更改子视图上的这些属性。

  • 从iOS 8开始,将 UISearchController 与 UINavigationController 一起使用需要将顶视图控制器的 definesPresentationContext 属性设置为 true。如果不这样做会导致难以检测和调试的细微错误。从 iOS & iPadOS 13 beta 开始,如果视图控制器的 navigationItem 具有 non-nil 搜索控件,当视图控制器显示在导航控制器中时,UINavigationController 会自动将该视图控制器的 definesPresentationContext 属性设置为 true。如果您要定位早期版本的 iOS,请在搜索控制器变为活动状态之前设置此属性。

  • UIRefreshControl 类不再直接修改其滚动视图的 contentInset。 相反,它对内容插入的调整将合并到滚动视图的 adjustContentInset 中。 唯一的例外是当滚动视图的 contentInsetAdjustmentBehavior 设置为 UIScrollViewContentInsetAdjustmentNever 时,在这种情况下,UIRefreshControl 实例将像以前的版本一样直接修改 contentInset

  • 如果通过覆盖 sizeThatFits 在 UITableView 中实现自调整单元格而不使用自动布局,则返回的高度将被解释为单元格的 contentView 所需的高度,UITableViewCell 会自动添加为单元格留出空间所需的任何其他高度 分隔器。如果以这种方式实现手动自调整大小,则在 UITableViewCell 上调用 sizeThatFits: 时,单元格的 contentView 宽度可以保证准确,以便在手动布局计算中使用。

  • Trait环境(例如视图和视图控制器)现在在初始化期间使用 traits 填充 traitCollection 属性。这些初始特征表示特征环境在添加到层次结构时将接收的最终特征的预测。因为在初始化期间填充的特征只是一个预测,它们可能与实际在层次结构中接收的特征不同。因此,在可能的情况下,您应该等待执行使用 traitCollection 的工作,直到视图或视图控制器的视图移动到层次结构中 - 意味着窗口返回非零值 - 这样您就不必丢弃任何工作,如果实际特征不同,则使用预测的特征完成。使用 traitCollection 的最佳时间是在布局期间,例如 layoutSubviews,viewWillLayoutSubviewsviewDidLayoutSubviews 内部。

  • 只有当特征值发生变化时,才会调用 traitCollectionDidChange: 方法。重要的是,由于特征集合现在初始化为目标层次结构中最终特征的预测,当初始预测特征与层次结构中的最终特征匹配时,特征环境添加到层次结构时将不会调用 traitCollectionDidChange:。因为 traitCollectionDidChange: 旨在作为无效回调来通知您一个或多个特征已更改,请审核此方法的现有实现,以及 UIContentContainer 方法willTransitionToTraitCollection:withTransitionCoordinator:,用于您可能依赖它的地方触发初始设置。懒惰地执行使用 traitCollection 的工作的最佳位置是在上面讨论的 layoutSubviews 方法之一,但请记住,这些布局方法在任何时候布局都会被调用,所以一定要避免在不需要时重复工作。

  • 您现在可以启用调试日志记录,以便在您自己的类上调用 traitCollectionDidChange:willTransitionToTraitCollection:withTransitionCoordinator: 时。使用以下启动参数打开日志记录:-UITraitCollectionChangeLoggingEnabled YES。您可能希望在使用此启动参数并从 Xcode 运行应用程序时暂时禁用主线程检查程序,以避免为不相关的类添加额外的日志消息。

  • UITableViewCell 类的 contentView 属性始终与前面和后面的相邻附件进行边对边布局。这简化了布局代码,因此想要正确的默认偏移的开发人员不再需要将其内容与内容视图边框或布局边距对齐,具体取决于尾部是否有附件。您现在应该始终在单元格内容视图的布局边距上布置代码以获取默认的系统插入。这些插入将根据单元格中可见的附件自动调整,以匹配系统的默认间距。

  • 您现在可以从创建 block 调用自定义初始化程序,该创建块通过 instantiateInitialViewController(creator:)instantiateViewController(identifier:creator:) 传递。这使您可以使用其他上下文和参数初始化视图控制器,同时利用通过 Interface Builder 在故事板中定义它们。自定义控制器初始化程序必须调用其 super.init(coder:) 方法并传递它通过创建块接收的编码器参数。

网络

  • 为了增强安全性,当服务器发送 Content-Type:application/octet-stream 时,NSURLSession 不再嗅探 MIME 类型。
  • NSURLRequestReloadRevalidatingCacheDataNSURLRequestReloadIgnoringLocalAndRemoteCacheData API现已可用。
  • 从 iOS 13 beta 4 开始,强制执行 NSMutableURLRequestHTTPBodyStream 属性的 copy 操作。如果在调用属性设置器后对 body 数据进行了修改,则 HTTP 请求中发送的数据将不包含该更变。调用该属性的 getter 不再返回 NSMutableData 引用,即使使用该类型的数据调用 setter 也是如此。从 iOS 13 beta 5 开始,使用 iOS 12 SDK 或以前的 SDK 构建的应用程序使用旧版行为。
  • CNCopyCurrentNetworkInfo API 返回的信息已无法反映真实情况。有关更多详细信息,请参阅更新的API文档和标题。
  • 包含 body 的 GET HTTP 方法的所有 NSURLSessionTask 实例现在都会抛出错误 NSURLErrorDataLengthExceedsMaximum
  • 删除了对代理自动配置(PAC)的 FTP 和文件URL方案的支持。HTTP 和 HTTPS 是 PAC 唯一支持的 URL 方案。这会影响所有 PAC 配置,包括但不限于使用“设置”,“系统偏好设置”,“配置文件”和 NSURLSession API(如connectionProxyDictionaryCFNetworkExecuteProxyAutoConfigurationURL)设置的配置。
  • NSURLSessionNSURLConnection API 不再支持 SPDY。服务器应使用 HTTP 2 或 HTTP 1.1。

音频

  • 现在可以在 AVAudioEngine 上启用语音处理模式。
  • 新的 AVAudioNode 类型可用于包装用户定义的 block,以实时发送或接收数据。
  • 基于 AVAudioEngine 的应用程序可以使用一种新方法来检索附加到 AVAudioEngine 实例的所有节点的列表。
  • AVAudioEnvironmentNode 中的新渲染模式基于输出设备自动选择最佳空间音频渲染算法。
  • 一个新的 AVAudioSession 属性允许在会话主动使用音频输入时播放系统声音和触觉。
  • 新的枚举 AVAudioSessionPromptStyle 根据系统中的其他音频活动通知应用程序应该播放哪种语音提示。
  • AVAudioSessionRouteSharingPolicy 现在允许应用指定路由共享策略,以便其音频和视频路由到与 AirPlay 相同的位置。
  • Audio Unit Extensions 现在支持所有宿主应用程序中可用的用户预设。
  • OpenAL框架已弃用,出于兼容性目的暂时保留。过渡到 AVAudioEngine 以获得 3D 音频功能。
  • AUGraph 已被弃用,转而支持 AVAudioEngine。
  • 不推荐使用应用间音频。使用 Audio Units 支持此功能。
  • 不推荐使用基于 CarbonAudio Units,在将来的版本中不再支持。
  • 不再支持旧版 Core Audio HAL 音频硬件插件。将音频服务器插件用于支持音频驱动程序。

音频共享

  • 音频共享与 AirPods(第1代或更高版本)和 PowerBeats Pro 兼容。需要 iPhone 8 或更高版本。

文章持续完善补充中,欢迎私信一起补充完善,有帮助麻烦点赞 ~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容

  • iOS 13 支持适配的机型 iPhone X、iPhone XR、iPhone XS、iPhone XS Max...
    不成活不疯魔阅读 43,905评论 22 131
  • 推荐文章 iOS Swift 自定义导航栏 FLNavigationBar 解决所有问题 WWDC 2019 Xc...
    松花蛋蘸醋阅读 2,877评论 1 9
  • 琦琦的简书阅读 122评论 0 0
  • 本文参加我是电影迷#活动,本人承诺,文章内容为原创,且未在其他平台发表过。 无法触碰的爱恋,融化在一生一世的拥抱中...
    人间小暖阅读 429评论 4 10
  • 午后窝在书房的沙发上,旋律轻盈的音乐响起,手里翻动着一本书。——我的小确幸 文|陆小墨 武汉的天气有点阴,好不容易...
    陆小墨阅读 1,883评论 4 21