對開源框架的修改(LightBlue-Objective-C)

頭文件:
主要修改的地方:

  • (void)didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic;
  • (void)didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error;

@property (strong,nonatomic) NSMutableDictionary *connectedCharacteristicsDic;

-(void)setNotification:(BOOL)enable forCharacteristicUUID:(CBUUID *)characteristicUUID;

-(void)writeValue:(NSData *)data forCharacteristicUUID:(CBUUID *)characteristicUUID;// Type:(CBCharacteristicWriteType)type;

//
//  BluetoothManager.h
//  LightBlue-Objective-C
//
//  Created by Deepak Sharma on 15/12/18.
//  Copyright ? 2018 Insanelydeepak. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <CoreBluetooth/CoreBluetooth.h>
#import "CBUUID+Additions.h"
#import "CBService+Additions.h"
#import "CBCharacteristic+Additions.h"
#define AUTO_CANCEL_CONNECT_TIMEOUT 2
#define PeripheralNotificationKeys_DisconnectNotif @"disconnectNotif"
#define PeripheralNotificationKeys_CharacteristicNotif @"characteristicNotif"

#ifdef DEBUG
    #define NSLog(fmt,...) do { \
        NSString *logString = [NSString stringWithFormat:(fmt), ##__VA_ARGS__]; \
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; \
        [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss.SSS"]; \
        NSString *dateString = [dateFormatter stringFromDate:[NSDate date]]; \
        NSString *fileName = [[NSString stringWithUTF8String:__FILE__] lastPathComponent]; \
        NSLog(@"%@ %@,[%d:%s],%@", dateString,fileName,__LINE__,_cmd, logString); \
    } while (0)
#else
    #define NSLog(...)
#endif


@protocol IDBluetoothDelegate <NSObject>
@optional
/**
 The callback function when the bluetooth has updated.

 - parameter state: The newest state
 */
-(void)didUpdateState:(CBCentralManager *)central;
/**
 The callback function when peripheral has been found.

 - parameter peripheral:        The peripheral has been found.
 - parameter advertisementData: The advertisement data.
 - parameter RSSI:              The signal strength.
 */
-(void)didDiscoverPeripheral:(CBPeripheral *)peripheral AdvertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)rssi;

/**
 The callback function when central manager connected the peripheral successfully.

 - parameter connectedPeripheral: The peripheral which connected successfully.
 */
-(void)didConnectedPeripheral:(CBPeripheral *)connectedPeripheral;
/**
 The callback function when central manager failed to connect the peripheral.

 - parameter connectedPeripheral: The peripheral which connected failure.
 - parameter error:               The connected failed error message.
 */
-(void)failToConnectPeripheral:(CBPeripheral *)peripheral Error:(NSError *)error;
/**
 The callback function when the services has been discovered.

 - parameter peripheral: Peripheral which provide this information and contain services information
 */
-(void)didDiscoverServices:(CBPeripheral *)peripheral;
/**
 The callback function when the peripheral disconnected.

 - parameter peripheral: The peripheral which provide this action
 */
-(void)didDisconnectPeripheral:(CBPeripheral *)peripheral;
/**
 The callback function when interrogate the peripheral is timeout

 - parameter peripheral: The peripheral which is failed to discover service
 */
-(void)didFailedToInterrogate:(CBPeripheral *)peripheral;
/**
 The callback function when discover characteritics successfully.

 - parameter service: The service information include characteritics.
 */
-(void)didDiscoverCharacteritics:(CBService *)service;
/**
 The callback function when discover characteritics successfully.

 - parameter service: The service information include characteritics.
 */
-(void)didFailToDiscoverCharacteritics:(NSError *)error;
/**
 The callback function when discover descriptor for characteristic successfully

 - parameter characteristic: The characteristic which has the descriptor
 */
-(void)didDiscoverDescriptors:(CBCharacteristic *)characteristic;
/**
 The callback function when failed to discover descriptor for characteristic

 - parameter error: The error message
 */
-(void)didFailToDiscoverDescriptors:(NSError *)error;

/**
 The callback function invoked when peripheral read value for the characteristic successfully

 - parameter characteristic: The characteristic withe the value
 */
-(void)didReadValueForCharacteristic:(CBCharacteristic *)characteristic;


- (void)didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic;

/**
 The callback function invoked when failed to read value for the characteristic

 - parameter error: The error message
 */
-(void)didFailToReadValueForCharacteristic:(NSError *)error;

- (void)didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error;

@end

@interface IDBluetoothManager : NSObject <CBCentralManagerDelegate, CBPeripheralDelegate>
+(IDBluetoothManager *)sharedInstance;
@property (strong,nonatomic) CBCentralManager *manager;
@property (strong, nonatomic) id<IDBluetoothDelegate> delegate;

@property (nonatomic) BOOL connected;
@property (strong,nonatomic) NSTimer *timeoutMonitor; /// Timeout monitor of connect to peripheral
@property (strong,nonatomic) NSTimer * interrogateMonitor ; /// Timeout monitor of interrogate the peripheral
@property (strong,nonatomic) NSNotificationCenter *notifCenter;
@property (nonatomic) BOOL isConnecting;
@property (strong,nonatomic) NSString *logs;
@property (strong,nonatomic) CBPeripheral *connectedPeripheral;
@property (strong,nonatomic) NSMutableArray *connectedServices;
@property (strong,nonatomic) NSMutableDictionary *connectedCharacteristicsDic;
-(void)startScanPeripheral;
-(void)stopScanPeripheral;
-(void)disconnectPeripheral;
-(void)discoverCharacteristics;
-(void)connectPeripheral:(CBPeripheral *)peripheral;
-(void)discoverDescriptor:(CBCharacteristic *)characteristic;
-(void)setNotification:(BOOL)enable forCharacteristic:(CBCharacteristic *)characteristic;
-(void)setNotification:(BOOL)enable forCharacteristicUUID:(CBUUID *)characteristicUUID;

-(void)readValueForCharacteristic:(CBCharacteristic *)characteristic;
-(void)writeValue:(NSData *)data forCharacteristic:(CBCharacteristic *)characteristic Type:(CBCharacteristicWriteType)type;


-(void)writeValue:(NSData *)data forCharacteristicUUID:(CBUUID *)characteristicUUID;// Type:(CBCharacteristicWriteType)type;
@end



實現部分:



#import "IDBluetoothManager.h"

/// Save the single instance
static IDBluetoothManager* sharedInstance = nil;

@implementation IDBluetoothManager

+ (IDBluetoothManager*)sharedInstance{
    // lazy instantiation
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[IDBluetoothManager alloc] init];
    });
    return sharedInstance;
}

- (id)init{
    self = [super init];
    if (self) {
        [self initCBCentralManager];

    }
    return self;
}
#pragma mark - Custom functions
/**
 Initialize CBCentralManager instance
 */
-(void)initCBCentralManager{
    _connected         = false;
    _isConnecting      = false;
    _connectedServices = [NSMutableArray array];
    _notifCenter       = [NSNotificationCenter defaultCenter];
    NSDictionary *dic  = @{CBCentralManagerOptionShowPowerAlertKey:[NSNumber numberWithBool:false]};
    _manager = [[CBCentralManager alloc]
                initWithDelegate:self
                queue:nil
                options:dic];
 }
/**
 Singleton pattern method
 - returns: Bluetooth single instance
 */


/**
 The method provides for starting scan near by peripheral
 */
-(void)startScanPeripheral{
    [_manager scanForPeripheralsWithServices:nil options:@{CBCentralManagerScanOptionAllowDuplicatesKey:[NSNumber numberWithBool:true]}];
  // [_manager scanForPeripheralsWithServices:[NSArray arrayWithObject:[CBUUID UUIDWithString:@"1910"]] options:nil];
}
/**
 The method provides for stopping scan near by peripheral
 */
-(void)stopScanPeripheral{
    [_manager stopScan];
}
/**
 The method provides for connecting the special peripheral

 - parameter peripher: The peripheral you want to connect
 */
-(void)connectPeripheral:(CBPeripheral *)peripheral{
    if (!_isConnecting) {
        _isConnecting = true;
        [_manager connectPeripheral:peripheral options:@{CBConnectPeripheralOptionNotifyOnDisconnectionKey:[NSNumber numberWithBool:true]}];
        _timeoutMonitor = [NSTimer scheduledTimerWithTimeInterval:AUTO_CANCEL_CONNECT_TIMEOUT target:self selector:@selector(connectTimeout:) userInfo:peripheral repeats:false];
    }
}
/**
 The method provides for disconnecting with the peripheral which has connected
 */
-(void)disconnectPeripheral{
    if (_connectedPeripheral != nil) {
        [_manager cancelPeripheralConnection:_connectedPeripheral];
        [self startScanPeripheral];
        _connectedPeripheral = nil;
    }
}
/**
 The method provides for the user who want to obtain the descriptor

 - parameter characteristic: The character which user want to obtain descriptor
 */
-(void)discoverDescriptor:(CBCharacteristic *)characteristic{
    if (_connectedPeripheral != nil)  {
        [_connectedPeripheral discoverDescriptorsForCharacteristic:characteristic];
    }
}
/**
 The method is invoked when connect peripheral is timeout

 - parameter timer: The timer touch off this selector
 */
-(void)connectTimeout:(NSTimer *)timer{
    if (_isConnecting) {
        _isConnecting = false;
        CBPeripheral *peripheral = [timer userInfo];
        [self connectPeripheral:peripheral];
        _timeoutMonitor = nil;
    }
}
/**
 This method is invoked when interrogate peripheral is timeout

 - parameter timer: The timer touch off this selector
 */
-(void)integrrogateTimeout:(NSTimer *)timer{
    [self disconnectPeripheral];
    CBPeripheral *peripheral = [timer userInfo];
    if (_delegate && [(id)_delegate respondsToSelector:@selector(didFailedToInterrogate:)]) {
        [_delegate didFailedToInterrogate:peripheral];
    }
}
/**
 This method provides for discovering the characteristics.
 */
-(void)discoverCharacteristics{
    if (_connectedPeripheral == nil) {
        return;
    }
    NSArray<CBService *> *services =_connectedPeripheral.services;
    if (services == nil || services.count < 1 ){ // Validate service array
        return;
    }

    for (CBService *service in services){
        [_connectedPeripheral discoverCharacteristics:nil forService:service];
    }
}
/**
 Read characteristic value from the peripheral

 - parameter characteristic: The characteristic which user should
 */
-(void)readValueForCharacteristic:(CBCharacteristic *)characteristic{
    if (_connectedPeripheral == nil) {
        return;
    }
    [_connectedPeripheral readValueForCharacteristic:characteristic];
}
/**
 Start or stop listening for the value update action

 - parameter enable:         If you want to start listening, the value is true, others is false
 - parameter characteristic: The characteristic which provides notifications
 */
-(void)setNotification:(BOOL)enable forCharacteristic:(CBCharacteristic *)characteristic{
    if (_connectedPeripheral == nil) {
        return;
    }
    NSLog(@"setNotification:>>value = %d",enable);
    [_connectedPeripheral setNotifyValue:enable forCharacteristic:characteristic];
}
-(void)setNotification:(BOOL)enable forCharacteristicUUID:(CBUUID *)characteristicUUID {
    if (_connectedCharacteristicsDic) {
        CBCharacteristic *characteristic = [_connectedCharacteristicsDic objectForKey:characteristicUUID];
        if (characteristic) {
            [_connectedPeripheral setNotifyValue:enable forCharacteristic:characteristic];
        } else {
            
        }
    } else {
        
    }
}
/**
 Write value to the peripheral which is connected

 - parameter data:           The data which will be written to peripheral
 - parameter characteristic: The characteristic information
 - parameter type:           The write of the operation
 */
-(void)writeValue:(NSData *)data forCharacteristic:(CBCharacteristic *)characteristic Type:(CBCharacteristicWriteType)type{
    if (_connectedPeripheral == nil) {
        return;
    }
    NSLog(@"write data to ble:%@",data);
    [_connectedPeripheral writeValue:data forCharacteristic:characteristic type:type];
}
-(void)writeValue:(NSData *)data forCharacteristicUUID:(CBUUID *)characteristicUUID {
    
    CBCharacteristic *characteristic = [self.connectedCharacteristicsDic objectForKey:characteristicUUID];
    CBCharacteristicProperties properties = characteristic.properties;
    
    CBCharacteristicWriteType  type = CBCharacteristicWriteWithResponse;
    if (properties & CBCharacteristicPropertyWriteWithoutResponse > 0) {
        type = CBCharacteristicWriteWithoutResponse;
    } else {
        type = CBCharacteristicWriteWithResponse;
    }
    [_connectedPeripheral writeValue:data forCharacteristic:characteristic type:type];

}
#pragma mark - Delegate
/**
 Invoked whenever the central manager's state has been updated.
 */

- (void)centralManagerDidUpdateState:(nonnull CBCentralManager *)central {
    // Determine the state of the peripheral
    switch ([central state]) {
        case CBCentralManagerStatePoweredOff:
             NSLog(@"State : Powered Off");
            break;
        case CBCentralManagerStatePoweredOn:
            NSLog(@"State : Powered On");
            break;
        case CBCentralManagerStateResetting:
            NSLog(@"State : Resetting");
            break;
        case CBCentralManagerStateUnauthorized:
            NSLog(@"State : Unauthorized");
            break;
        case CBCentralManagerStateUnknown:
            NSLog(@"State : Unknown");
            break;
        case CBCentralManagerStateUnsupported:
            NSLog(@"State : Unsupported");
            break;
    }
    if (_delegate && [(id)_delegate respondsToSelector:@selector(didUpdateState:)]) {
        [_delegate didUpdateState:central];

    }
}
/**
 This method is invoked while scanning, upon the discovery of peripheral by central

 - parameter central:           The central manager providing this update.
 - parameter peripheral:        The discovered peripheral.
 - parameter advertisementData: A dictionary containing any advertisement and scan response data.
 - parameter RSSI:              The current RSSI of peripheral, in dBm. A value of 127 is reserved and indicates the RSSI
 *                                was not available.
 */
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI{
    //    NSLog(@"discover peripheral: %@; advertisementData: %@; RSSI: %@", peripheral, advertisementData, RSSI);
    NSLog(@"Bluetooth Manager --> didDiscoverPeripheral:%@ RSSI:%@", peripheral.name, RSSI);

    if (_delegate && [(id)_delegate respondsToSelector:@selector(didDiscoverPeripheral:AdvertisementData:RSSI:)]) {
        [_delegate didDiscoverPeripheral:peripheral AdvertisementData:advertisementData RSSI:RSSI];
    }
 }
/**
 This method is invoked when a connection succeeded

 - parameter central:    The central manager providing this information.
 - parameter peripheral: The peripheral that has connected.
 */
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
    NSLog(@"Bluetooth Manager --> didConnectPeripheral: %@",peripheral.name);
    _isConnecting  = false;
    if (_timeoutMonitor != nil) {
        [_timeoutMonitor invalidate];
        _timeoutMonitor = nil;
    }
    _connected = true;
    _connectedPeripheral = peripheral;

    if (_delegate && [(id)_delegate respondsToSelector:@selector(didConnectedPeripheral:)]) {
        [_delegate didConnectedPeripheral:peripheral];
    }
    [self stopScanPeripheral];
    peripheral.delegate = self;
    [peripheral discoverServices:nil];

    _interrogateMonitor = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(integrrogateTimeout:) userInfo:peripheral repeats:false];
}
/**
 This method is invoked where a connection failed.

 - parameter central:    The central manager providing this information.
 - parameter peripheral: The peripheral that you tried to connect.
 - parameter error:      The error infomation about connecting failed.
 */
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
    NSLog(@"Bluetooth Manager --> didFailToConnectPeripheral");
    _isConnecting = false;
    if (_timeoutMonitor != nil) {
        [_timeoutMonitor invalidate];
        _timeoutMonitor = nil;
    }
    _connected = false;
    if (_delegate && [(id)_delegate respondsToSelector:@selector(failToConnectPeripheral:Error:)]) {
        [_delegate failToConnectPeripheral:peripheral Error:error];
    }
  }
/**
 The method is invoked where services were discovered.

 - parameter peripheral: The peripheral with service informations.
 - parameter error:      Errot message when discovered services.
 */
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{
    NSLog(@"Bluetooth Manager --> didDiscoverServices");
    _connectedPeripheral = peripheral;
    if (error != nil) {
        NSLog(@"Bluetooth Manager --> Discover Services Error, error:%@",error.localizedDescription);
        return ;
    }
    // If discover services, then invalidate the timeout monitor
    if (_interrogateMonitor != nil) {
        [_interrogateMonitor invalidate];
        _interrogateMonitor = nil;
    }

    if (_delegate && [(id)_delegate respondsToSelector:@selector(didDiscoverServices:)]) {
        [_delegate didDiscoverServices:peripheral];
    }
}
/**
 The method is invoked where characteristics were discovered.

 - parameter peripheral: The peripheral provide this information
 - parameter service:    The service included the characteristics.
 - parameter error:      If an error occurred, the cause of the failure.
 */
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{
    NSLog(@"Bluetooth Manager --> didDiscoverCharacteristicsForService");
    _connectedPeripheral = peripheral;
    if (error != nil) {
        NSLog(@"Bluetooth Manager --> Fail to discover characteristics! Error:%@",error.localizedDescription);
        if (_delegate && [(id)_delegate respondsToSelector:@selector(didFailToDiscoverCharacteritics:)]) {
             [_delegate didFailToDiscoverCharacteritics:error];
        }
        return ;
    }
    if (_connectedCharacteristicsDic == nil) {
        _connectedCharacteristicsDic = [NSMutableDictionary dictionary];
    }
    for (CBCharacteristic *cbchara in service.characteristics) {
        [_connectedCharacteristicsDic setObject:cbchara forKey:cbchara.UUID];
    }
    
    if (_delegate && [(id)_delegate respondsToSelector:@selector(didDiscoverCharacteritics:)]) {
        [_delegate didDiscoverCharacteritics:service];
    }
    
  }
/**
 This method is invoked when the peripheral has found the descriptor for the characteristic

 - parameter peripheral:     The peripheral providing this information
 - parameter characteristic: The characteristic which has the descriptor
 - parameter error:          The error message
 */

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverDescriptorsForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
    NSLog(@"Bluetooth Manager --> didDiscoverDescriptorsForCharacteristic");
    if (error != nil) {
        NSLog(@"Bluetooth Manager --> Fail to discover descriptor for characteristic Error:%@",error.localizedDescription);
        if (_delegate && [(id)_delegate respondsToSelector:@selector(didFailToDiscoverDescriptors:)]) {
            [_delegate didFailToDiscoverDescriptors:error];
        }
        return;
    }
    if (_delegate && [(id)_delegate respondsToSelector:@selector(didDiscoverDescriptors:)]) {
        [_delegate didDiscoverDescriptors:characteristic];
    }
  }
/**
 This method is invoked when the peripheral has been disconnected.

 - parameter central:    The central manager providing this information
 - parameter peripheral: The disconnected peripheral
 - parameter error:      The error message
 */
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
    NSLog(@"Bluetooth Manager --> didDisconnectPeripheral");
    _connected = false;
    if (_delegate && [(id)_delegate respondsToSelector:@selector(didDisconnectPeripheral:)]) {
         [_delegate didDisconnectPeripheral:peripheral];
    }
    [_notifCenter postNotificationName:PeripheralNotificationKeys_DisconnectNotif object:self];
}
/**
 Thie method is invoked when the user call the peripheral.readValueForCharacteristic

 - parameter peripheral:     The periphreal which call the method
 - parameter characteristic: The characteristic with the new value
 - parameter error:          The error message
 */
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
    NSLog(@"Bluetooth Manager --> didUpdateValueForCharacteristic, %@:>%@",characteristic.UUID.UUIDString, characteristic.value);
    if (error){
        NSLog(@"Bluetooth Manager --> Failed to read value for the characteristic. Error:%@",error.localizedDescription);
        if (_delegate && [(id)_delegate respondsToSelector:@selector(didFailToReadValueForCharacteristic:)]) {
            [_delegate didFailToReadValueForCharacteristic:error];
        }
        return;
    }
    NSLog(@"_delegate:>%@",_delegate);
    if (_delegate && [_delegate respondsToSelector:@selector(didReadValueForCharacteristic:)]) {
        [_delegate didReadValueForCharacteristic:characteristic];
    }
 }

- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
    
    NSLog(@">>>Bluetooth Manager --> didUpdateNotificationStateForCharacteristic, %@:>%@,isnotify:%d  error:%@",characteristic.UUID.UUIDString, characteristic.value,characteristic.isNotifying, error);
    
    if (_delegate && [_delegate respondsToSelector:@selector(didUpdateNotificationStateForCharacteristic:)]) {
        [_delegate didUpdateNotificationStateForCharacteristic:characteristic];
    }
}

- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
    NSLog(@">>>Bluetooth Manager --> didWriteValueForCharacteristic, %@:>%@,  error:%@",characteristic.UUID.UUIDString, characteristic.value, error);
    
    if (_delegate && [_delegate respondsToSelector:@selector(didWriteValueForCharacteristic:error:)]) {
        [_delegate didWriteValueForCharacteristic:characteristic error:error];
    }

}
@end

以下是應用場景:

image.png

代碼說明:
在添加藍牙設備后發送指令讓設備返回設備信息。
步驟:添加,使能notify,寫入指令,接收信息。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,461評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,538評論 3 417
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,423評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,991評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,761評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,207評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,268評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,419評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,959評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,653評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,901評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,678評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,978評論 2 374

推薦閱讀更多精彩內容