2 İşlemeler 879346c789 ... a3ad5b1dfa

Yazar SHA1 Mesaj Tarih
  Fenix Wang a3ad5b1dfa no message 8 yıl önce
  Fenix Wang 22ad428fd1 no message 8 yıl önce
100 değiştirilmiş dosya ile 4618 ekleme ve 958 silme
  1. BIN
      NIMDemo/NIM.xcworkspace/xcuserdata/Fenix.xcuserdatad/UserInterfaceState.xcuserstate
  2. 46 18
      NIMDemo/NIMDemo.xcodeproj/project.pbxproj
  3. 15 3
      NIMDemo/NIMDemo/AppDelegate.m
  4. 392 233
      NIMDemo/NIMDemo/Base.lproj/Main.storyboard
  5. 15 0
      NIMDemo/NIMDemo/BeFollowedViewController.h
  6. 261 0
      NIMDemo/NIMDemo/BeFollowedViewController.m
  7. 1 0
      NIMDemo/NIMDemo/ChatConfigViewController.m
  8. 2 0
      NIMDemo/NIMDemo/CityPickerViewController.h
  9. 43 41
      NIMDemo/NIMDemo/CityPickerViewController.m
  10. 2 1
      NIMDemo/NIMDemo/Classes/LayoutConfig/NTESCellLayoutConfig.m
  11. 4 2
      NIMDemo/NIMDemo/Classes/Sections/Card/ViewController/NTESTeamListViewController.m
  12. 1 1
      NIMDemo/NIMDemo/Classes/Sections/Contact/ViewController/Contact/NTESContactAddFriendViewController.m
  13. 10 1
      NIMDemo/NIMDemo/Classes/Sections/Session/Model/Object/NTESCustomAttachmentDecoder.m
  14. 1 0
      NIMDemo/NIMDemo/Classes/Sections/Session/Model/Object/NTESCustomAttachmentDefines.h
  15. 3 0
      NIMDemo/NIMDemo/Classes/Sections/Session/Model/Object/NTESSessionMsgConverter.h
  16. 11 0
      NIMDemo/NIMDemo/Classes/Sections/Session/Model/Object/NTESSessionMsgConverter.m
  17. 20 0
      NIMDemo/NIMDemo/Classes/Sections/Session/Model/Object/NTESShareAttachment.h
  18. 79 0
      NIMDemo/NIMDemo/Classes/Sections/Session/Model/Object/NTESShareAttachment.m
  19. 13 0
      NIMDemo/NIMDemo/Classes/Sections/Session/View/SessionCell/SessionContentView/NTESSessionShareContentView.h
  20. 106 0
      NIMDemo/NIMDemo/Classes/Sections/Session/View/SessionCell/SessionContentView/NTESSessionShareContentView.m
  21. 7 0
      NIMDemo/NIMDemo/Classes/Sections/Session/ViewController/NTESSessionLocalHistoryViewController.m
  22. 2 0
      NIMDemo/NIMDemo/Classes/Sections/Session/ViewController/NTESSessionViewController.h
  23. 113 16
      NIMDemo/NIMDemo/Classes/Sections/Session/ViewController/NTESSessionViewController.m
  24. 4 0
      NIMDemo/NIMDemo/Classes/Sections/SessionList/ViewController/NTESSessionListViewController.m
  25. 16 13
      NIMDemo/NIMDemo/Classes/Sections/Setting/UInfo/NTESAliasSettingViewController.m
  26. 1 1
      NIMDemo/NIMDemo/Classes/Sections/Setting/UInfo/NTESGenderSettingViewController.m
  27. 2 1
      NIMDemo/NIMDemo/Classes/Util/NTESDemoConfig.m
  28. 1 1
      NIMDemo/NIMDemo/Classes/Util/NTESUserUtil.m
  29. 111 7
      NIMDemo/NIMDemo/ContactViewController.m
  30. 4 3
      NIMDemo/NIMDemo/CreateGroupViewController.m
  31. 13 0
      NIMDemo/NIMDemo/ForgetTableViewController.h
  32. 168 0
      NIMDemo/NIMDemo/ForgetTableViewController.m
  33. 5 2
      NIMDemo/NIMDemo/FriendListViewController.h
  34. 108 16
      NIMDemo/NIMDemo/FriendListViewController.m
  35. 3 3
      NIMDemo/NIMDemo/FriendRequestTableViewCell.h
  36. 86 8
      NIMDemo/NIMDemo/FriendRequestTableViewCell.m
  37. 381 36
      NIMDemo/NIMDemo/FriendRequestViewController.m
  38. 152 11
      NIMDemo/NIMDemo/FriendViewController.m
  39. 1 0
      NIMDemo/NIMDemo/GiftTopBarItem.h
  40. 52 12
      NIMDemo/NIMDemo/GiftTopBarItem.m
  41. 16 0
      NIMDemo/NIMDemo/GroupAvatarTableViewCell.h
  42. 53 0
      NIMDemo/NIMDemo/GroupAvatarTableViewCell.m
  43. 157 8
      NIMDemo/NIMDemo/GroupInfoViewController.m
  44. 15 10
      NIMDemo/NIMDemo/GroupMoreTableViewCell.m
  45. 12 35
      NIMDemo/NIMDemo/GroupMoreTableViewController.m
  46. 106 20
      NIMDemo/NIMDemo/GroupTableController.m
  47. 7 3
      NIMDemo/NIMDemo/GroupTableViewCell.m
  48. 56 0
      NIMDemo/NIMDemo/HttpRequest/HttpRequest.h
  49. 379 11
      NIMDemo/NIMDemo/HttpRequest/HttpRequest.m
  50. 0 201
      NIMDemo/NIMDemo/ImagePagerViewController.m
  51. 21 0
      NIMDemo/NIMDemo/Images.xcassets/Whosay/input_border.imageset/Contents.json
  52. BIN
      NIMDemo/NIMDemo/Images.xcassets/Whosay/input_border.imageset/input_border.png
  53. 21 0
      NIMDemo/NIMDemo/Images.xcassets/Whosay/ss_login_bg.imageset/Contents.json
  54. BIN
      NIMDemo/NIMDemo/Images.xcassets/Whosay/ss_login_bg.imageset/login_bg.png
  55. 21 0
      NIMDemo/NIMDemo/Images.xcassets/Whosay/white_bordered_btn.imageset/Contents.json
  56. BIN
      NIMDemo/NIMDemo/Images.xcassets/Whosay/white_bordered_btn.imageset/white_bordered_btn.png
  57. 13 0
      NIMDemo/NIMDemo/IntroViewController.h
  58. 129 0
      NIMDemo/NIMDemo/IntroViewController.m
  59. 11 0
      NIMDemo/NIMDemo/LocationManager.m
  60. 66 2
      NIMDemo/NIMDemo/LoginViewController.m
  61. 46 33
      NIMDemo/NIMDemo/MyUserInfoViewController.m
  62. 4 0
      NIMDemo/NIMDemo/PSCityPickerView/PSCityPickerView.m
  63. 4 2
      NIMDemo/NIMDemo/PayOptionViewController.m
  64. 140 11
      NIMDemo/NIMDemo/RechargeViewController.m
  65. 10 3
      NIMDemo/NIMDemo/RegisterViewController.m
  66. 12 1
      NIMDemo/NIMDemo/SectionGroup/GroupDescTableViewCell.m
  67. 82 3
      NIMDemo/NIMDemo/SectionGroup/GroupMenberTableViewCell.m
  68. 3 0
      NIMDemo/NIMDemo/SectionSetting/AddPhotoViewController.h
  69. 147 14
      NIMDemo/NIMDemo/SectionSetting/AddPhotoViewController.m
  70. 10 2
      NIMDemo/NIMDemo/SectionSetting/ChangePasswordViewController.m
  71. 1 1
      NIMDemo/NIMDemo/SectionSetting/SettingSecurityViewController.m
  72. 4 2
      NIMDemo/NIMDemo/SectionTrade/MyTradeTableViewCell.m
  73. 11 12
      NIMDemo/NIMDemo/SectionTrade/MyTradeViewController.m
  74. 1 0
      NIMDemo/NIMDemo/SectionTrade/TradeData.h
  75. 1 0
      NIMDemo/NIMDemo/SectionTrade/TradeData.m
  76. 1 0
      NIMDemo/NIMDemo/SectionTrade/TradeDetailViewController.h
  77. 101 21
      NIMDemo/NIMDemo/SectionTrade/TradeDetailViewController.m
  78. 25 12
      NIMDemo/NIMDemo/SectionTrade/TradeModifyViewController.m
  79. 28 3
      NIMDemo/NIMDemo/SectionTrade/TradePublishManager.m
  80. 5 3
      NIMDemo/NIMDemo/SectionTrade/TradeTableViewCell.m
  81. 1 0
      NIMDemo/NIMDemo/SectionTrade/TradeUtil.h
  82. 25 5
      NIMDemo/NIMDemo/SectionTrade/TradeUtil.m
  83. 37 13
      NIMDemo/NIMDemo/SectionTrade/TradeViewController.m
  84. 15 0
      NIMDemo/NIMDemo/SectionTrade/WhosayActivity.h
  85. 67 0
      NIMDemo/NIMDemo/SectionTrade/WhosayActivity.m
  86. 12 0
      NIMDemo/NIMDemo/SettingAccountViewController.m
  87. 46 25
      NIMDemo/NIMDemo/SettingTableViewController.m
  88. 1 0
      NIMDemo/NIMDemo/SettingTopTableViewCell.h
  89. 192 25
      NIMDemo/NIMDemo/SettingTopTableViewCell.m
  90. 1 0
      NIMDemo/NIMDemo/SocialCommentDetailTableViewCell.m
  91. 17 0
      NIMDemo/NIMDemo/SocialDetailTableViewCell.m
  92. 3 0
      NIMDemo/NIMDemo/SocialDetailViewController.h
  93. 20 2
      NIMDemo/NIMDemo/SocialDetailViewController.m
  94. 69 11
      NIMDemo/NIMDemo/SocialPublishViewController.m
  95. 28 6
      NIMDemo/NIMDemo/SocialTableViewCell.m
  96. 5 0
      NIMDemo/NIMDemo/SocialTableViewController.h
  97. 62 11
      NIMDemo/NIMDemo/SocialTableViewController.m
  98. 1 1
      NIMDemo/NIMDemo/SocialTopTableViewCell.h
  99. 38 10
      NIMDemo/NIMDemo/SocialTopTableViewCell.m
  100. 4 6
      NIMDemo/NIMDemo/Supporting Files/Info.plist

BIN
NIMDemo/NIM.xcworkspace/xcuserdata/Fenix.xcuserdatad/UserInterfaceState.xcuserstate


+ 46 - 18
NIMDemo/NIMDemo.xcodeproj/project.pbxproj

@@ -185,7 +185,6 @@
 		907DBE851E5C777300317C36 /* NTESRecordSelectView.m in Sources */ = {isa = PBXBuildFile; fileRef = 907DBE841E5C777300317C36 /* NTESRecordSelectView.m */; };
 		9B2726C0A3FC2E1873247A6B /* libPods-NIMDemo-NIM.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 74D3CBBCCF66D9A6D453BB43 /* libPods-NIMDemo-NIM.a */; };
 		AE2AA6851A7CD35C00CFF013 /* UIView+NTES.m in Sources */ = {isa = PBXBuildFile; fileRef = AE2AA6841A7CD35C00CFF013 /* UIView+NTES.m */; };
-		AE5882F61A6F47E10070536A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = AE5882F51A6F47E10070536A /* Images.xcassets */; };
 		AE58995A1A6FA7AC0070536A /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AE5899591A6FA7AC0070536A /* SystemConfiguration.framework */; };
 		AEA87FE11A81CAD600ACC3BA /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AEA87FE01A81CAD500ACC3BA /* AVFoundation.framework */; };
 		BD52DB3E1B8F300E00434D0E /* NTESCADisplayLinkHolder.m in Sources */ = {isa = PBXBuildFile; fileRef = BD52DB3D1B8F300E00434D0E /* NTESCADisplayLinkHolder.m */; };
@@ -195,8 +194,12 @@
 		BDB02D271E09172F00262A50 /* NTESNetDetectViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = BDB02D251E09172F00262A50 /* NTESNetDetectViewController.xib */; };
 		BDB0FC691BA7E6D30066654D /* NTESGLView.m in Sources */ = {isa = PBXBuildFile; fileRef = BDB0FC681BA7E6D30066654D /* NTESGLView.m */; };
 		C40F4C4B1EF15BC7002B197A /* GiftTopBarItem.m in Sources */ = {isa = PBXBuildFile; fileRef = C40F4C4A1EF15BC7002B197A /* GiftTopBarItem.m */; };
+		C412DDB61F3B2DB3004F0CEE /* WhosayActivity.m in Sources */ = {isa = PBXBuildFile; fileRef = C412DDB51F3B2DB3004F0CEE /* WhosayActivity.m */; };
+		C412DDB91F3B374E004F0CEE /* NTESShareAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = C412DDB81F3B374E004F0CEE /* NTESShareAttachment.m */; };
+		C412DDBC1F3B3B55004F0CEE /* NTESSessionShareContentView.m in Sources */ = {isa = PBXBuildFile; fileRef = C412DDBB1F3B3B55004F0CEE /* NTESSessionShareContentView.m */; };
 		C41B6EF81EEFB30D00AD1F53 /* RechargeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C41B6EF71EEFB30D00AD1F53 /* RechargeViewController.m */; };
 		C41B6EFC1EEFB67500AD1F53 /* RechargeItem.m in Sources */ = {isa = PBXBuildFile; fileRef = C41B6EFB1EEFB67500AD1F53 /* RechargeItem.m */; };
+		C421B9BE1F769B040090649A /* IntroViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C421B9BD1F769B040090649A /* IntroViewController.m */; };
 		C4246CF11F075D08008CD291 /* TradeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C4246CF01F075D08008CD291 /* TradeViewController.m */; };
 		C4246CF41F075D58008CD291 /* TradeTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = C4246CF31F075D58008CD291 /* TradeTableViewCell.m */; };
 		C4246CF71F075F59008CD291 /* TradeData.m in Sources */ = {isa = PBXBuildFile; fileRef = C4246CF61F075F59008CD291 /* TradeData.m */; };
@@ -206,6 +209,7 @@
 		C445A2B61F1E0335005E88B6 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C445A2B51F1E0335005E88B6 /* UIKit.framework */; };
 		C445A2B81F1E033F005E88B6 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C445A2B71F1E033F005E88B6 /* Foundation.framework */; };
 		C445A2BA1F1E0353005E88B6 /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C445A2B91F1E0353005E88B6 /* CoreMotion.framework */; };
+		C47564801F8F5AC90042C271 /* GroupAvatarTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = C475647F1F8F5AC90042C271 /* GroupAvatarTableViewCell.m */; };
 		C482C2F51F09DAA800EF2B71 /* TradePublishManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C482C2F41F09DAA800EF2B71 /* TradePublishManager.m */; };
 		C482C2FB1F0A110E00EF2B71 /* TradePostTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = C482C2FA1F0A110E00EF2B71 /* TradePostTableViewCell.m */; };
 		C482C2FE1F0A3B0000EF2B71 /* SettingTopTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = C482C2FD1F0A3B0000EF2B71 /* SettingTopTableViewCell.m */; };
@@ -243,6 +247,8 @@
 		C4B639511ED57DAB004288FC /* city.plist in Resources */ = {isa = PBXBuildFile; fileRef = C4B6394E1ED57DAB004288FC /* city.plist */; };
 		C4B639521ED57DAB004288FC /* PSCityPickerView.m in Sources */ = {isa = PBXBuildFile; fileRef = C4B639501ED57DAB004288FC /* PSCityPickerView.m */; };
 		C4B639571ED581E2004288FC /* User.m in Sources */ = {isa = PBXBuildFile; fileRef = C4B639561ED581E2004288FC /* User.m */; };
+		C4BEB3881F6B676300CF77D3 /* ForgetTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C4BEB3871F6B676300CF77D3 /* ForgetTableViewController.m */; };
+		C4BEB38B1F6E537A00CF77D3 /* BeFollowedViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C4BEB38A1F6E537A00CF77D3 /* BeFollowedViewController.m */; };
 		C4D4C9261ED7C2A900ADD7B7 /* GroupTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = C4D4C9251ED7C2A900ADD7B7 /* GroupTableViewCell.m */; };
 		C4D4C9321ED7C37F00ADD7B7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = C4D4C9281ED7C37F00ADD7B7 /* AppDelegate.m */; };
 		C4D4C9331ED7C37F00ADD7B7 /* LoginViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C4D4C92A1ED7C37F00ADD7B7 /* LoginViewController.m */; };
@@ -253,6 +259,7 @@
 		C4D4C93C1ED7C3DE00ADD7B7 /* CreateGroupViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C4D4C9391ED7C3DE00ADD7B7 /* CreateGroupViewController.m */; };
 		C4D4C93D1ED7C3DE00ADD7B7 /* GroupTableController.m in Sources */ = {isa = PBXBuildFile; fileRef = C4D4C93B1ED7C3DE00ADD7B7 /* GroupTableController.m */; };
 		C4D4C9401ED81F2100ADD7B7 /* CityPickerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C4D4C93F1ED81F2100ADD7B7 /* CityPickerViewController.m */; };
+		C4D872FE1F905720007B2646 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C4D872FD1F905720007B2646 /* Images.xcassets */; };
 		C4D8F12C1ED48657002F9F3A /* AFHTTPSessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C4D8F1201ED48657002F9F3A /* AFHTTPSessionManager.m */; };
 		C4D8F12D1ED48657002F9F3A /* AFNetworkReachabilityManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C4D8F1231ED48657002F9F3A /* AFNetworkReachabilityManager.m */; };
 		C4D8F12E1ED48657002F9F3A /* AFSecurityPolicy.m in Sources */ = {isa = PBXBuildFile; fileRef = C4D8F1251ED48657002F9F3A /* AFSecurityPolicy.m */; };
@@ -310,7 +317,6 @@
 		C4F1D0F81EFA197300A04B28 /* SocialItemData.m in Sources */ = {isa = PBXBuildFile; fileRef = C4F1D0F71EFA197300A04B28 /* SocialItemData.m */; };
 		C4F1D0FE1F010E1D00A04B28 /* SocialCommentData.m in Sources */ = {isa = PBXBuildFile; fileRef = C4F1D0FD1F010E1D00A04B28 /* SocialCommentData.m */; };
 		C4F1D1531F03891700A04B28 /* SocialDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C4F1D1521F03891700A04B28 /* SocialDetailViewController.m */; };
-		C4F1D1571F0389AA00A04B28 /* ImagePagerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C4F1D1561F0389AA00A04B28 /* ImagePagerViewController.m */; };
 		C4F1D15D1F03DDCA00A04B28 /* SocialDetailTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = C4F1D15C1F03DDCA00A04B28 /* SocialDetailTableViewCell.m */; };
 		C4F1D1601F03DDE500A04B28 /* SocialCommentDetailTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = C4F1D15F1F03DDE500A04B28 /* SocialCommentDetailTableViewCell.m */; };
 		E4168E291B6A364800F3D35D /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E4168E281B6A364800F3D35D /* AudioToolbox.framework */; };
@@ -656,7 +662,6 @@
 		AE2AA6841A7CD35C00CFF013 /* UIView+NTES.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = "UIView+NTES.m"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
 		AE5882E51A6F47E10070536A /* NIM.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NIM.app; sourceTree = BUILT_PRODUCTS_DIR; };
 		AE5882E91A6F47E10070536A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
-		AE5882F51A6F47E10070536A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
 		AE5899591A6FA7AC0070536A /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
 		AEA87FE01A81CAD500ACC3BA /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
 		AEB8367F1A772C2F00E7493E /* NIMDemo-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NIMDemo-Prefix.pch"; sourceTree = "<group>"; };
@@ -671,10 +676,18 @@
 		BDB0FC681BA7E6D30066654D /* NTESGLView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NTESGLView.m; sourceTree = "<group>"; };
 		C40F4C491EF15BC7002B197A /* GiftTopBarItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GiftTopBarItem.h; sourceTree = "<group>"; };
 		C40F4C4A1EF15BC7002B197A /* GiftTopBarItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GiftTopBarItem.m; sourceTree = "<group>"; };
+		C412DDB41F3B2DB3004F0CEE /* WhosayActivity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WhosayActivity.h; path = ../../../../../fenix/XCode_Project/NIM_iOS_Demo_v3/NIMDemo/NIMDemo/SectionTrade/WhosayActivity.h; sourceTree = "<group>"; };
+		C412DDB51F3B2DB3004F0CEE /* WhosayActivity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = WhosayActivity.m; path = ../../../../../fenix/XCode_Project/NIM_iOS_Demo_v3/NIMDemo/NIMDemo/SectionTrade/WhosayActivity.m; sourceTree = "<group>"; };
+		C412DDB71F3B374E004F0CEE /* NTESShareAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NTESShareAttachment.h; path = ../../../../../../../../../../fenix/XCode_Project/NIM_iOS_Demo_v3/NIMDemo/NIMDemo/Classes/Sections/Session/Model/Object/NTESShareAttachment.h; sourceTree = "<group>"; };
+		C412DDB81F3B374E004F0CEE /* NTESShareAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NTESShareAttachment.m; path = ../../../../../../../../../../fenix/XCode_Project/NIM_iOS_Demo_v3/NIMDemo/NIMDemo/Classes/Sections/Session/Model/Object/NTESShareAttachment.m; sourceTree = "<group>"; };
+		C412DDBA1F3B3B55004F0CEE /* NTESSessionShareContentView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NTESSessionShareContentView.h; path = ../../../../../../../../../../../fenix/XCode_Project/NIM_iOS_Demo_v3/NIMDemo/NIMDemo/Classes/Sections/Session/View/SessionCell/SessionContentView/NTESSessionShareContentView.h; sourceTree = "<group>"; };
+		C412DDBB1F3B3B55004F0CEE /* NTESSessionShareContentView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NTESSessionShareContentView.m; path = ../../../../../../../../../../../fenix/XCode_Project/NIM_iOS_Demo_v3/NIMDemo/NIMDemo/Classes/Sections/Session/View/SessionCell/SessionContentView/NTESSessionShareContentView.m; sourceTree = "<group>"; };
 		C41B6EF61EEFB30D00AD1F53 /* RechargeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RechargeViewController.h; sourceTree = "<group>"; };
 		C41B6EF71EEFB30D00AD1F53 /* RechargeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RechargeViewController.m; sourceTree = "<group>"; };
 		C41B6EFA1EEFB67500AD1F53 /* RechargeItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RechargeItem.h; sourceTree = "<group>"; };
 		C41B6EFB1EEFB67500AD1F53 /* RechargeItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RechargeItem.m; sourceTree = "<group>"; };
+		C421B9BC1F769B040090649A /* IntroViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IntroViewController.h; path = ../../../../../fenix/XCode_Project/NIM_iOS_Demo_v3/NIMDemo/NIMDemo/IntroViewController.h; sourceTree = "<group>"; };
+		C421B9BD1F769B040090649A /* IntroViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IntroViewController.m; path = ../../../../../fenix/XCode_Project/NIM_iOS_Demo_v3/NIMDemo/NIMDemo/IntroViewController.m; sourceTree = "<group>"; };
 		C4246CEF1F075D08008CD291 /* TradeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TradeViewController.h; path = ../../../../../fenix/XCode_Project/NIM_iOS_Demo_v3/NIMDemo/NIMDemo/SectionTrade/TradeViewController.h; sourceTree = "<group>"; };
 		C4246CF01F075D08008CD291 /* TradeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TradeViewController.m; path = ../../../../../fenix/XCode_Project/NIM_iOS_Demo_v3/NIMDemo/NIMDemo/SectionTrade/TradeViewController.m; sourceTree = "<group>"; };
 		C4246CF21F075D58008CD291 /* TradeTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TradeTableViewCell.h; path = ../../../../../fenix/XCode_Project/NIM_iOS_Demo_v3/NIMDemo/NIMDemo/SectionTrade/TradeTableViewCell.h; sourceTree = "<group>"; };
@@ -687,6 +700,8 @@
 		C445A2B51F1E0335005E88B6 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
 		C445A2B71F1E033F005E88B6 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
 		C445A2B91F1E0353005E88B6 /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = System/Library/Frameworks/CoreMotion.framework; sourceTree = SDKROOT; };
+		C475647E1F8F5AC90042C271 /* GroupAvatarTableViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = GroupAvatarTableViewCell.h; path = ../../../../../fenix/XCode_Project/NIM_iOS_Demo_v3/NIMDemo/NIMDemo/GroupAvatarTableViewCell.h; sourceTree = "<group>"; };
+		C475647F1F8F5AC90042C271 /* GroupAvatarTableViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = GroupAvatarTableViewCell.m; path = ../../../../../fenix/XCode_Project/NIM_iOS_Demo_v3/NIMDemo/NIMDemo/GroupAvatarTableViewCell.m; sourceTree = "<group>"; };
 		C482C2F31F09DAA800EF2B71 /* TradePublishManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TradePublishManager.h; path = ../../../../../fenix/XCode_Project/NIM_iOS_Demo_v3/NIMDemo/NIMDemo/SectionTrade/TradePublishManager.h; sourceTree = "<group>"; };
 		C482C2F41F09DAA800EF2B71 /* TradePublishManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TradePublishManager.m; path = ../../../../../fenix/XCode_Project/NIM_iOS_Demo_v3/NIMDemo/NIMDemo/SectionTrade/TradePublishManager.m; sourceTree = "<group>"; };
 		C482C2F91F0A110E00EF2B71 /* TradePostTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TradePostTableViewCell.h; path = ../../../../../fenix/XCode_Project/NIM_iOS_Demo_v3/NIMDemo/NIMDemo/SectionTrade/TradePostTableViewCell.h; sourceTree = "<group>"; };
@@ -761,6 +776,10 @@
 		C4B639501ED57DAB004288FC /* PSCityPickerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PSCityPickerView.m; path = PSCityPickerView/PSCityPickerView.m; sourceTree = "<group>"; };
 		C4B639551ED581E2004288FC /* User.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = User.h; sourceTree = "<group>"; };
 		C4B639561ED581E2004288FC /* User.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = User.m; sourceTree = "<group>"; };
+		C4BEB3861F6B676300CF77D3 /* ForgetTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ForgetTableViewController.h; path = ../../../../../fenix/XCode_Project/NIM_iOS_Demo_v3/NIMDemo/NIMDemo/ForgetTableViewController.h; sourceTree = "<group>"; };
+		C4BEB3871F6B676300CF77D3 /* ForgetTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ForgetTableViewController.m; path = ../../../../../fenix/XCode_Project/NIM_iOS_Demo_v3/NIMDemo/NIMDemo/ForgetTableViewController.m; sourceTree = "<group>"; };
+		C4BEB3891F6E537A00CF77D3 /* BeFollowedViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BeFollowedViewController.h; sourceTree = "<group>"; };
+		C4BEB38A1F6E537A00CF77D3 /* BeFollowedViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BeFollowedViewController.m; sourceTree = "<group>"; };
 		C4D4C9241ED7C2A900ADD7B7 /* GroupTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GroupTableViewCell.h; sourceTree = "<group>"; };
 		C4D4C9251ED7C2A900ADD7B7 /* GroupTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GroupTableViewCell.m; sourceTree = "<group>"; };
 		C4D4C9271ED7C37F00ADD7B7 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
@@ -780,6 +799,7 @@
 		C4D4C93B1ED7C3DE00ADD7B7 /* GroupTableController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GroupTableController.m; sourceTree = "<group>"; };
 		C4D4C93E1ED81F2100ADD7B7 /* CityPickerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CityPickerViewController.h; sourceTree = "<group>"; };
 		C4D4C93F1ED81F2100ADD7B7 /* CityPickerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CityPickerViewController.m; sourceTree = "<group>"; };
+		C4D872FD1F905720007B2646 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = ../../../../../fenix/XCode_Project/NIM_iOS_Demo_v3/NIMDemo/NIMDemo/Images.xcassets; sourceTree = "<group>"; };
 		C4D8F11F1ED48657002F9F3A /* AFHTTPSessionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AFHTTPSessionManager.h; path = AFNetworking/AFHTTPSessionManager.h; sourceTree = "<group>"; };
 		C4D8F1201ED48657002F9F3A /* AFHTTPSessionManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AFHTTPSessionManager.m; path = AFNetworking/AFHTTPSessionManager.m; sourceTree = "<group>"; };
 		C4D8F1211ED48657002F9F3A /* AFNetworking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AFNetworking.h; path = AFNetworking/AFNetworking.h; sourceTree = "<group>"; };
@@ -950,8 +970,6 @@
 		C4F1D0FD1F010E1D00A04B28 /* SocialCommentData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SocialCommentData.m; sourceTree = "<group>"; };
 		C4F1D1511F03891700A04B28 /* SocialDetailViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SocialDetailViewController.h; sourceTree = "<group>"; };
 		C4F1D1521F03891700A04B28 /* SocialDetailViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SocialDetailViewController.m; sourceTree = "<group>"; };
-		C4F1D1551F0389AA00A04B28 /* ImagePagerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImagePagerViewController.h; sourceTree = "<group>"; };
-		C4F1D1561F0389AA00A04B28 /* ImagePagerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImagePagerViewController.m; sourceTree = "<group>"; };
 		C4F1D15B1F03DDCA00A04B28 /* SocialDetailTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SocialDetailTableViewCell.h; sourceTree = "<group>"; };
 		C4F1D15C1F03DDCA00A04B28 /* SocialDetailTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SocialDetailTableViewCell.m; sourceTree = "<group>"; };
 		C4F1D15E1F03DDE500A04B28 /* SocialCommentDetailTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SocialCommentDetailTableViewCell.h; sourceTree = "<group>"; };
@@ -1493,6 +1511,8 @@
 				61E470811B7D963E00F4A1BF /* NTESWhiteboardAttachment.m */,
 				C482C3081F0B857800EF2B71 /* NTESGiftAttachment.h */,
 				C482C3091F0B857800EF2B71 /* NTESGiftAttachment.m */,
+				C412DDB71F3B374E004F0CEE /* NTESShareAttachment.h */,
+				C412DDB81F3B374E004F0CEE /* NTESShareAttachment.m */,
 			);
 			path = Object;
 			sourceTree = "<group>";
@@ -1541,6 +1561,8 @@
 				61E7B5871DCF39E200F19E83 /* NTESSessionTipContentView.m */,
 				C482C30B1F0B923300EF2B71 /* NTESSessionGiftContentView.h */,
 				C482C30C1F0B923300EF2B71 /* NTESSessionGiftContentView.m */,
+				C412DDBA1F3B3B55004F0CEE /* NTESSessionShareContentView.h */,
+				C412DDBB1F3B3B55004F0CEE /* NTESSessionShareContentView.m */,
 			);
 			path = SessionContentView;
 			sourceTree = "<group>";
@@ -1893,7 +1915,6 @@
 			isa = PBXGroup;
 			children = (
 				C4DB33361F1E25A30080D72F /* Alipay */,
-				C4F1D1541F03897F00A04B28 /* Utils */,
 				C4F1D0F21EFA177C00A04B28 /* Network */,
 				C41B6EF91EEFB64900AD1F53 /* Recharge */,
 				C4D4C9271ED7C37F00ADD7B7 /* AppDelegate.h */,
@@ -1906,6 +1927,8 @@
 				C4D4C92F1ED7C37F00ADD7B7 /* TabBarController.m */,
 				C4D4C9301ED7C37F00ADD7B7 /* ViewController.h */,
 				C4D4C9311ED7C37F00ADD7B7 /* ViewController.m */,
+				C421B9BC1F769B040090649A /* IntroViewController.h */,
+				C421B9BD1F769B040090649A /* IntroViewController.m */,
 				C4B639541ED58186004288FC /* User */,
 				C4B639531ED57DBB004288FC /* CityPicker */,
 				C4D8F14D1ED4883F002F9F3A /* LaunchScreen.storyboard */,
@@ -1917,9 +1940,9 @@
 				C4B146331EF2333900819893 /* SectionSetting */,
 				C4D8F1321ED48660002F9F3A /* AFNetworking */,
 				61F728281A7B23A40076C096 /* Classes */,
-				AE5882F51A6F47E10070536A /* Images.xcassets */,
 				AEB8367F1A772C2F00E7493E /* NIMDemo-Prefix.pch */,
 				6195CD3E1A8C74DB00F3E239 /* NTESGlobalMacro.h */,
+				C4D872FD1F905720007B2646 /* Images.xcassets */,
 				AE5882E81A6F47E10070536A /* Supporting Files */,
 			);
 			name = whosay;
@@ -1999,6 +2022,8 @@
 				C482C3371F14B32300EF2B71 /* TradeModifyViewController.m */,
 				C482C3391F14B43A00EF2B71 /* TradeModifyImageView.h */,
 				C482C33A1F14B43A00EF2B71 /* TradeModifyImageView.m */,
+				C412DDB41F3B2DB3004F0CEE /* WhosayActivity.h */,
+				C412DDB51F3B2DB3004F0CEE /* WhosayActivity.m */,
 			);
 			name = SectionTrade;
 			sourceTree = "<group>";
@@ -2018,6 +2043,8 @@
 				C482C32B1F13686A00EF2B71 /* GroupMenberIcon.m */,
 				C482C32D1F13716A00EF2B71 /* GroupToogleTableViewCell.h */,
 				C482C32E1F13716A00EF2B71 /* GroupToogleTableViewCell.m */,
+				C475647E1F8F5AC90042C271 /* GroupAvatarTableViewCell.h */,
+				C475647F1F8F5AC90042C271 /* GroupAvatarTableViewCell.m */,
 			);
 			name = GroupCell;
 			sourceTree = "<group>";
@@ -2121,6 +2148,10 @@
 				C4DB33E01F2CA5B90080D72F /* FriendListViewController.m */,
 				C4DB33E21F2CA6750080D72F /* FriendListTableViewCell.h */,
 				C4DB33E31F2CA6750080D72F /* FriendListTableViewCell.m */,
+				C4BEB3861F6B676300CF77D3 /* ForgetTableViewController.h */,
+				C4BEB3871F6B676300CF77D3 /* ForgetTableViewController.m */,
+				C4BEB3891F6E537A00CF77D3 /* BeFollowedViewController.h */,
+				C4BEB38A1F6E537A00CF77D3 /* BeFollowedViewController.m */,
 			);
 			name = User;
 			sourceTree = "<group>";
@@ -2319,15 +2350,6 @@
 			name = Network;
 			sourceTree = "<group>";
 		};
-		C4F1D1541F03897F00A04B28 /* Utils */ = {
-			isa = PBXGroup;
-			children = (
-				C4F1D1551F0389AA00A04B28 /* ImagePagerViewController.h */,
-				C4F1D1561F0389AA00A04B28 /* ImagePagerViewController.m */,
-			);
-			name = Utils;
-			sourceTree = "<group>";
-		};
 		E45E17771CA8CB6200C4ED69 /* Log */ = {
 			isa = PBXGroup;
 			children = (
@@ -2446,7 +2468,6 @@
 				610B1E041AFDDE04006454EA /* video_chat_tip_HangUp.aac in Resources */,
 				610B1E021AFDDE04006454EA /* video_connect_chat_tip_sender.aac in Resources */,
 				61E4712B1B7D963E00F4A1BF /* NTESLoginViewController.xib in Resources */,
-				AE5882F61A6F47E10070536A /* Images.xcassets in Resources */,
 				61A18A4B1DC73B96001FD538 /* NIMKitEmoticon.bundle in Resources */,
 				E45E17821CA8CBA500C4ED69 /* NTESLogViewController.xib in Resources */,
 				E4ED12DD1B6B07EA00316496 /* message.wav in Resources */,
@@ -2463,6 +2484,7 @@
 				6173AEC51BAAB94400854D49 /* NTESUserInfoSettingViewController.xib in Resources */,
 				61E471631B7D963E00F4A1BF /* NTESAboutViewController.xib in Resources */,
 				61E471651B7D963E00F4A1BF /* NTESSettingViewController.xib in Resources */,
+				C4D872FE1F905720007B2646 /* Images.xcassets in Resources */,
 				C4D8F1521ED48840002F9F3A /* Main.storyboard in Resources */,
 				61E471221B7D963E00F4A1BF /* NTESCustomSysNotificationViewController.xib in Resources */,
 				61E471241B7D963E00F4A1BF /* NTESSystemNotificationCell.xib in Resources */,
@@ -2543,6 +2565,7 @@
 				C482C3191F10A00900EF2B71 /* GroupInfoViewController.m in Sources */,
 				C4DB33CD1F299A0C0080D72F /* ComplainDetailViewController.m in Sources */,
 				61E4719C1B7D9C8300F4A1BF /* NTESSessionViewController.m in Sources */,
+				C412DDBC1F3B3B55004F0CEE /* NTESSessionShareContentView.m in Sources */,
 				61E4712F1B7D963E00F4A1BF /* NTESChartletAttachment.m in Sources */,
 				8351CB721E977D9000DF4866 /* NTESContactDataCell.m in Sources */,
 				61E4714F1B7D963E00F4A1BF /* NTESVideoViewController.m in Sources */,
@@ -2576,6 +2599,7 @@
 				C4DB33C71F298A710080D72F /* UserConfigViewController.m in Sources */,
 				61E470F61B7D963E00F4A1BF /* NTESColorButtonCell.m in Sources */,
 				C4DB33C41F29863B0080D72F /* ChatConfigViewController.m in Sources */,
+				C421B9BE1F769B040090649A /* IntroViewController.m in Sources */,
 				61518A561CA233BB0061C4A9 /* NTESDemoService.m in Sources */,
 				C482C32C1F13686A00EF2B71 /* GroupMenberIcon.m in Sources */,
 				C4D4C9361ED7C37F00ADD7B7 /* TabBarController.m in Sources */,
@@ -2602,6 +2626,7 @@
 				C4D8F12E1ED48657002F9F3A /* AFSecurityPolicy.m in Sources */,
 				C4DB33A61F20A83E0080D72F /* UserGiftViewController.m in Sources */,
 				C4D8F1311ED48658002F9F3A /* AFURLSessionManager.m in Sources */,
+				C412DDB91F3B374E004F0CEE /* NTESShareAttachment.m in Sources */,
 				61E4715B1B7D963E00F4A1BF /* NTESTextHeaderView.m in Sources */,
 				61E471551B7D963E00F4A1BF /* NTESVideoChatViewController.m in Sources */,
 				61E471021B7D963E00F4A1BF /* NTESJionTeamViewController.m in Sources */,
@@ -2671,7 +2696,6 @@
 				C482C3321F14749800EF2B71 /* TradeUtil.m in Sources */,
 				61B5D7EB1C21331600B52DBF /* NTESPageView.m in Sources */,
 				C4D4C93D1ED7C3DE00ADD7B7 /* GroupTableController.m in Sources */,
-				C4F1D1571F0389AA00A04B28 /* ImagePagerViewController.m in Sources */,
 				61E4713D1B7D963E00F4A1BF /* NTESSessionSnapchatContentView.m in Sources */,
 				61E471281B7D963E00F4A1BF /* NTESLoginManager.m in Sources */,
 				612CACEE1BB1484C00C348B5 /* NTESContactDataMember.m in Sources */,
@@ -2723,6 +2747,7 @@
 				C4DB33D81F2C7ECC0080D72F /* FriendRequestTableViewCell.m in Sources */,
 				61E4718A1B7D96AA00F4A1BF /* NTESBundleSetting.m in Sources */,
 				AE2AA6851A7CD35C00CFF013 /* UIView+NTES.m in Sources */,
+				C4BEB3881F6B676300CF77D3 /* ForgetTableViewController.m in Sources */,
 				C4DB33B21F25A69F0080D72F /* NearUserTableViewCell.m in Sources */,
 				E45E177A1CA8CB6200C4ED69 /* NTESLogUploader.m in Sources */,
 				C4DB33B81F25DA6F0080D72F /* PrivacyViewController.m in Sources */,
@@ -2737,6 +2762,7 @@
 				C482C3511F1CC04800EF2B71 /* SettingSecurityViewController.m in Sources */,
 				C4F1D0F51EFA17DF00A04B28 /* HttpRequest.m in Sources */,
 				C4DB33921F1E25A30080D72F /* base64.m in Sources */,
+				C412DDB61F3B2DB3004F0CEE /* WhosayActivity.m in Sources */,
 				611ABF041B3CF4FC00B8706C /* NTESMarginButton.m in Sources */,
 				61E4715E1B7D963E00F4A1BF /* NTESSessionListViewController.m in Sources */,
 				C4DB33961F1E25A30080D72F /* RSADataVerifier.m in Sources */,
@@ -2744,10 +2770,12 @@
 				61E4715F1B7D963E00F4A1BF /* NTESNoDisturbSettingViewController.m in Sources */,
 				83F32B731E94EFE200E594E0 /* NTESSubscribeManager.m in Sources */,
 				C4246CF71F075F59008CD291 /* TradeData.m in Sources */,
+				C4BEB38B1F6E537A00CF77D3 /* BeFollowedViewController.m in Sources */,
 				61E471641B7D963E00F4A1BF /* NTESSettingViewController.m in Sources */,
 				C4D4C9341ED7C37F00ADD7B7 /* main.m in Sources */,
 				6173AED51BAAC8E700854D49 /* NTESEmailSettingViewController.m in Sources */,
 				03A4CA001AC2B79700E45E03 /* UIActionSheet+NTESBlock.m in Sources */,
+				C47564801F8F5AC90042C271 /* GroupAvatarTableViewCell.m in Sources */,
 				61E471431B7D963E00F4A1BF /* NTESFileTransSelectViewController.m in Sources */,
 				C482C34B1F187A4100EF2B71 /* UserInfoViewController.m in Sources */,
 				61E4713E1B7D963E00F4A1BF /* NTESSessionWhiteBoardContentView.m in Sources */,

+ 15 - 3
NIMDemo/NIMDemo/AppDelegate.m

@@ -108,9 +108,21 @@ NSString *NTESNotificationLogout = @"NTESNotificationLogout";
 
 - (void)setupMainViewController
 {
-    UIStoryboard *board = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
-    UINavigationController *nav = [board instantiateViewControllerWithIdentifier:@"NavController"];
-    self.window.rootViewController = nav;
+    //读取存入的数组
+    NSArray *introArr = [[NSUserDefaults standardUserDefaults] objectForKey:@"ShowIntroFlag"];
+    
+    if(introArr)
+    {
+        UIStoryboard *board = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
+        UINavigationController *nav = [board instantiateViewControllerWithIdentifier:@"NavController"];
+        self.window.rootViewController = nav;
+    }
+    else
+    {
+        UIStoryboard *board = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
+        UIViewController *nav = [board instantiateViewControllerWithIdentifier:@"Intro"];
+        self.window.rootViewController = nav;
+    }
 }
 
 - (void)commonInitListenEvents

Dosya farkı çok büyük olduğundan ihmal edildi
+ 392 - 233
NIMDemo/NIMDemo/Base.lproj/Main.storyboard


+ 15 - 0
NIMDemo/NIMDemo/BeFollowedViewController.h

@@ -0,0 +1,15 @@
+//
+//  BeFollowedViewController.h
+//  NIMDemo
+//
+//  Created by Fenix Wang on 2017/9/17.
+//  Copyright © 2017年 Netease. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface BeFollowedViewController : UIViewController<UITableViewDelegate, UITableViewDataSource>
+
+@property (weak, nonatomic) IBOutlet UITableView *tableView;
+
+@end

+ 261 - 0
NIMDemo/NIMDemo/BeFollowedViewController.m

@@ -0,0 +1,261 @@
+//
+//  BeFollowedViewController.m
+//  NIMDemo
+//
+//  Created by Fenix Wang on 2017/9/17.
+//  Copyright © 2017年 Netease. All rights reserved.
+//
+
+#import "BeFollowedViewController.h"
+#import "User.h"
+#import "FriendListTableViewCell.h"
+#import "NTESContactUtilItem.h"
+#import "NTESContactDataMember.h"
+#import "NTESContactUtilCell.h"
+#import "NTESContactDataCell.h"
+#import "UIView+Toast.h"
+#import "HttpRequest.h"
+#import "NTESSessionViewController.h"
+#import "FriendListViewController.h"
+#import "ContactViewController.h"
+
+@interface BeFollowedViewController ()<NTESContactUtilCellDelegate,
+NIMContactDataCellDelegate, UISearchBarDelegate>
+
+@property (nonatomic, strong) UISearchController    *searchController;
+@property (nonatomic, strong) GroupedContacts       *contacts;
+@property (nonatomic, strong) NSMutableArray        *requestArr;
+@property (nonatomic, strong) NSMutableArray        *searchArr;
+
+@end
+
+@implementation BeFollowedViewController
+
+- (void)viewDidLoad {
+    [super viewDidLoad];
+    
+    _searchArr = [[NSMutableArray alloc] init];
+    
+    _searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
+    _searchController.hidesNavigationBarDuringPresentation = NO;
+    _searchController.searchBar.tintColor = UIColor.whiteColor;
+    //_searchController.delegate = self;
+    _searchController.dimsBackgroundDuringPresentation = NO;
+    _searchController.searchBar.delegate = self;
+    [self.view addSubview:_searchController.searchBar];
+                         
+    
+    __weak typeof(self) wself = self;
+    [[HttpRequest shared] befollowedList:^(NSMutableArray<FriendRequestData *> * _Nullable dataArr) {
+        
+        wself.requestArr = dataArr;
+        [wself fetchUserInfos];
+        
+    } failure:^{
+        [wself fetchUserInfos];
+    }];
+}
+
+- (void)didReceiveMemoryWarning {
+    [super didReceiveMemoryWarning];
+    // Dispose of any resources that can be recreated.
+}
+
+- (void)fetchUserInfos{
+    __weak typeof(self) wself = self;
+    NSArray *followList = [[User sharedInfo] followList];
+    [[NIMSDK sharedSDK].userManager fetchUserInfos:followList completion:^(NSArray<NIMUser *> * _Nullable users, NSError * _Nullable error) {
+        [wself prepareData];
+    }];
+}
+
+- (void)prepareData{
+    
+    NSMutableArray *infoArr = [NSMutableArray array];
+    for (NSString *userId in self.requestArr) {
+        NIMKitInfo *info           = [[NIMKit sharedKit] infoByUser:userId option:nil];
+        NTESContactDataMember *contact = [[NTESContactDataMember alloc] init];
+        contact.info               = info;
+        [infoArr addObject:contact];
+    }
+    
+    NSInteger systemCount = [[[NIMSDK sharedSDK] systemNotificationManager] allUnreadCount];
+    _contacts = [[GroupedContacts alloc] initWithMembers:infoArr];
+    
+    [self.tableView reloadData];
+}
+
+- (void)viewWillAppear:(BOOL)animated{
+    [super viewWillAppear:animated];
+    [self.navigationItem setTitle:@"我的粉丝"];
+}
+
+- (void)viewDidAppear:(BOOL)animated{
+    [super viewDidAppear:animated];
+    [self prepareData];
+}
+
+- (void)viewWillDisappear:(BOOL)animated
+{
+    [super viewWillDisappear:animated];
+    [self.searchController setActive:NO];
+}
+
+- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
+{
+    NSLog(@"textDidChange %@  %@", searchBar.text, searchText);
+    
+    if(searchText.length > 0)
+    {
+        [self.searchArr removeAllObjects];
+        for(int i=0; i<_contacts.groupCount; i++)
+        {
+            NSArray *members = [_contacts membersOfGroup:i];
+            for(int j=0; j<members.count; j++)
+            {
+                id member = [members objectAtIndex:j];
+                if(![member isKindOfClass:[NTESContactDataMember class]])
+                {
+                    continue;
+                }
+                NTESContactDataMember *dataMember = member;
+                if([dataMember.info.showName containsString:searchText])
+                {
+                    [_searchArr addObject:member];
+                }
+            }
+        }
+    }
+    else
+    {
+        [self.searchArr removeAllObjects];
+    }
+    
+    [self.tableView reloadData];
+}
+
+- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
+{
+    [self.searchArr removeAllObjects];
+    [self.tableView reloadData];
+}
+
+#pragma mark - Table view data source
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
+    if(_searchArr.count)
+        return 1;
+    return [_contacts groupCount];
+}
+
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+    if(_searchArr.count)
+        return _searchArr.count;
+    return [_contacts memberCountOfGroup:section];
+}
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+    
+    id contactItem = nil;
+    if(_searchArr.count)
+    {
+        contactItem = [_searchArr objectAtIndex:indexPath.row];
+    }
+    else
+    {
+        contactItem = [_contacts memberOfIndex:indexPath];
+    }
+    
+    NSString * cellId = [contactItem reuseId];
+    UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:cellId];
+    if (!cell) {
+        Class cellClazz = NSClassFromString([contactItem cellName]);
+        cell = [[cellClazz alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
+    }
+    if ([contactItem showAccessoryView]) {
+        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
+    }else{
+        cell.accessoryType = UITableViewCellAccessoryNone;
+    }
+    if ([cell isKindOfClass:[NTESContactUtilCell class]]) {
+        [(NTESContactUtilCell *)cell refreshWithContactItem:contactItem];
+        [(NTESContactUtilCell *)cell setDelegate:self];
+    }else{
+        [(NTESContactDataCell *)cell refreshUser:contactItem];
+        [(NTESContactDataCell *)cell setDelegate:self];
+    }
+    return cell;
+}
+
+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
+    [tableView deselectRowAtIndexPath:indexPath animated:YES];
+    
+    id<NTESContactItem> contactItem = nil;
+    if(_searchArr.count)
+    {
+        contactItem = [_searchArr objectAtIndex:indexPath.row];
+    }
+    else
+    {
+        contactItem = (id<NTESContactItem>)[_contacts memberOfIndex:indexPath];
+    }
+    if ([contactItem respondsToSelector:@selector(selName)] && [contactItem selName].length) {
+        SEL sel = NSSelectorFromString([contactItem selName]);
+        SuppressPerformSelectorLeakWarning([self performSelector:sel withObject:nil]);
+    }
+    else if (contactItem.vcName.length) {
+        Class clazz = NSClassFromString(contactItem.vcName);
+        UIViewController * vc = [[clazz alloc] initWithNibName:nil bundle:nil];
+        [self.navigationController pushViewController:vc animated:YES];
+    }
+    else if ([contactItem isKindOfClass:[NTESContactUtilMember class]] && ((NTESContactUtilMember *)contactItem).storyboardId.length > 0){
+        UIStoryboard *board = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
+        UIViewController *vc = [board instantiateViewControllerWithIdentifier:((NTESContactUtilMember *)contactItem).storyboardId];
+        if([vc isKindOfClass:[FriendRequestViewController class]])
+        {
+            [((FriendRequestViewController *)vc) setDataArr:_requestArr];
+        }
+        [self.navigationController pushViewController:vc animated:YES];
+    }
+    else if([contactItem respondsToSelector:@selector(userId)]){
+        NSString * friendId   = contactItem.userId;
+        [self onPressAvatar:friendId];
+    }
+    
+}
+
+- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
+    id<NTESContactItem> contactItem = (id<NTESContactItem>)[_contacts memberOfIndex:indexPath];
+    return contactItem.uiHeight;
+}
+
+- (NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
+    if(_searchArr.count)
+        return nil;
+    return [_contacts titleOfGroup:section];
+}
+
+- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
+    if(_searchArr.count)
+        return nil;
+    return _contacts.sortedGroupTitles;
+}
+
+- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
+    return index + 1;
+}
+
+#pragma mark - NIMContactDataCellDelegate
+- (void)onPressAvatar:(NSString *)memberId{
+    //    NIMSession *session = [NIMSession session:memberId type:NIMSessionTypeP2P];
+    //    NTESSessionViewController *vc = [[NTESSessionViewController alloc] initWithSession:session];
+    //    [self.navigationController pushViewController:vc animated:YES];
+    [User showUserInfo:memberId viewController:self];
+}
+
+#pragma mark - NTESContactUtilCellDelegate
+- (void)onPressUtilImage:(NSString *)content{
+    //[self.view makeToast:[NSString stringWithFormat:@"点我干嘛 我是<%@>",content] duration:2.0 position:CSToastPositionCenter];
+}
+
+@end

+ 1 - 0
NIMDemo/NIMDemo/ChatConfigViewController.m

@@ -94,6 +94,7 @@
             UIStoryboard *board = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
             UserInfoViewController *vc = [board instantiateViewControllerWithIdentifier:@"UserInfo"];
             [vc setUserId:_userId];
+            
             [self.navigationController pushViewController:vc animated:YES];
             break;
         }

+ 2 - 0
NIMDemo/NIMDemo/CityPickerViewController.h

@@ -10,4 +10,6 @@
 
 @interface CityPickerViewController : UIViewController
 
+@property (nonatomic, assign) BOOL isChangeAddress;
+
 @end

+ 43 - 41
NIMDemo/NIMDemo/CityPickerViewController.m

@@ -11,6 +11,7 @@
 #import "User.h"
 #import "SVProgressHUD.h"
 #import "AFNetworking/AFNetworking.h"
+#import "HttpRequest.h"
 
 
 @interface CityPickerViewController () <PSCityPickerViewDelegate>
@@ -70,55 +71,56 @@
 }
 
 - (void)citySelected{
-    
+    if(_isChangeAddress)
+    {
+        [self changeAddress];
+    }
+    else
+    {
+        [self changeLocation];
+    }
+}
+
+
+- (void)changeLocation{
     [SVProgressHUD show];
-    User *user = [User sharedInfo];
     
-    NSDictionary *parameters = @{@"id":[NSString stringWithFormat:@"%d", user.userId],
-                                 @"province":self.province,
-                                 @"city":self.city,
-                                 @"district":self.district
-                                 };
-    NSString *urlString = @"http://whosay.dashgame.com/index.php?m=who&c=index&a=reset_location";
-    //请求的managers
-    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
-    manager.responseSerializer = [AFJSONResponseSerializer new];
-    manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/html", nil];
+    [[HttpRequest shared] resetLocation:self.province city:self.city district:self.district success:^{
+        [SVProgressHUD dismiss];
+        [self.navigationController popViewControllerAnimated:YES];
+    } failure:^{
+        [SVProgressHUD dismiss];
+    }];
+}
 
-    //请求的方式:POST
-    
-    NSLog(@"%@", parameters);
+- (void)changeAddress{
     
-    [manager POST:urlString parameters:parameters progress:nil success:^(NSURLSessionDataTask *task, id responseObject) {
-        
-        [SVProgressHUD dismiss];
-        
-        NSLog(@"请求成功,服务器返回的信息%@", responseObject);
-        NSDictionary * dic = responseObject;
-        int code = [[dic valueForKey:@"c"] intValue];
-        NSDictionary *data = (NSDictionary *)[dic objectForKey:@"d"];
-        
-        NSLog(@"Json解析结果 = %d   %@", code, data);
-        
-        if(code == 0)
+    [SVProgressHUD show];
+    NSString *address = nil;
+    if([_province isEqualToString:_city])
+    {
+        if([_city isEqualToString:_district])
         {
-            
-            user.province = self.province;
-            user.city = self.city;
-            user.district = self.district;
-            
-            user.provinceRoomId = [data objectForKey:@"province"];
-            user.cityRoomId = [data objectForKey:@"city"];
-            user.districtRoomId = [data objectForKey:@"district"];
-        
-            [self.navigationController popViewControllerAnimated:YES];
+            address = _district;
         }
-        
-    } failure:^(NSURLSessionDataTask *task, NSError * error) {
+        else
+        {
+            address = [NSString stringWithFormat:@"%@%@", _city, _district];
+        }
+    }
+    else
+    {
+        address = [NSString stringWithFormat:@"%@%@%@", _province, _city, _district];
+    }
+    NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
+    [parameters setValue:address forKey:@"address"];
+    [[HttpRequest shared] updateUserInfo:parameters success:^{
+        [SVProgressHUD dismiss];
+        [User sharedInfo].userInfo.address = address;
+        [self.navigationController popViewControllerAnimated:YES];
+    } failure:^{
         [SVProgressHUD dismiss];
-        NSLog(@"请求失败,服务器返回的错误信息%@",error);
     }];
-
 }
 
 @end

+ 2 - 1
NIMDemo/NIMDemo/Classes/LayoutConfig/NTESCellLayoutConfig.m

@@ -28,7 +28,8 @@
                    @"NTESSnapchatAttachment",
                    @"NTESChartletAttachment",
                    @"NTESWhiteboardAttachment",
-                   @"NTESGiftAttachment"
+                   @"NTESGiftAttachment",
+                   @"NTESShareAttachment"
                    ];
         _sessionCustomconfig = [[NTESSessionCustomContentConfig alloc] init];
         _chatroomTextConfig = [[NTESChatroomTextContentConfig alloc] init];

+ 4 - 2
NIMDemo/NIMDemo/Classes/Sections/Card/ViewController/NTESTeamListViewController.m

@@ -8,6 +8,7 @@
 
 #import "NTESTeamListViewController.h"
 #import "NTESSessionViewController.h"
+#import "User.h"
 
 @interface NTESTeamListViewController () <UITableViewDelegate, UITableViewDataSource,NIMTeamManagerDelegate> {
 }
@@ -88,13 +89,14 @@
 
 - (void)viewDidLoad{
     [super viewDidLoad];
-    self.navigationItem.title = @"高级群组";
+    //self.navigationItem.title = @"高级群组";
+    self.navigationItem.title = @"我的群组";
 }
 
 - (NSMutableArray *)fetchTeams{
     NSMutableArray *myTeams = [[NSMutableArray alloc]init];
     for (NIMTeam *team in [NIMSDK sharedSDK].teamManager.allMyTeams) {
-        if (team.type == NIMTeamTypeAdvanced) {
+        if (team.type == NIMTeamTypeAdvanced && ![[User sharedInfo] isSystemTeam:team.teamId]) {
             [myTeams addObject:team];
         }
     }

+ 1 - 1
NIMDemo/NIMDemo/Classes/Sections/Contact/ViewController/Contact/NTESContactAddFriendViewController.m

@@ -94,7 +94,7 @@
     __weak typeof(self) wself = self;
     [SVProgressHUD show];
     
-    [[HttpRequest shared] userInfo:userId success:^(UserInfo * _Nullable userInfo) {
+    [[HttpRequest shared] userInfo:userId search:YES success:^(UserInfo * _Nullable userInfo) {
         
         [User showUserInfoWithData:userInfo viewController:wself];
         

+ 10 - 1
NIMDemo/NIMDemo/Classes/Sections/Session/Model/Object/NTESCustomAttachmentDecoder.m

@@ -13,6 +13,7 @@
 #import "NTESChartletAttachment.h"
 #import "NTESGiftAttachment.h"
 #import "NTESWhiteboardAttachment.h"
+#import "NTESShareAttachment.h"
 #import "NSDictionary+NTESJson.h"
 #import "NTESSessionUtil.h"
 
@@ -64,6 +65,14 @@
                     [((NTESGiftAttachment *)attachment) handleGiftMessage:data];
                 }
                     break;
+                case CustomMessageTypeShare:
+                {
+                    attachment = [[NTESShareAttachment alloc] init];
+                    ((NTESShareAttachment *)attachment).info = [data jsonString:CMValue];
+                    ((NTESShareAttachment *)attachment).thumb = [data jsonString:CMURL];
+                    ((NTESShareAttachment *)attachment).tradeId = [data jsonString:@"tradeId"];
+                }
+                    break;
                 default:
                     break;
             }
@@ -92,7 +101,7 @@
         NSInteger flag = [((NTESWhiteboardAttachment *)attachment) flag];
         check = ((flag >= CustomWhiteboardFlagInvite) && (flag <= CustomWhiteboardFlagClose)) ? YES : NO;
     }
-    else if ([attachment isKindOfClass:[NTESGiftAttachment class]]) {
+    else if ([attachment isKindOfClass:[NTESGiftAttachment class]] || [attachment isKindOfClass:[NTESShareAttachment class]]) {
         check = YES;
     }
     return check;

+ 1 - 0
NIMDemo/NIMDemo/Classes/Sections/Session/Model/Object/NTESCustomAttachmentDefines.h

@@ -17,6 +17,7 @@ typedef NS_ENUM(NSInteger,NTESCustomMessageType){
     CustomMessageTypeChartlet   = 3, //贴图表情
     CustomMessageTypeWhiteboard = 4,  //白板会话
     CustomMessageTypeGift       = 5, //送礼物
+    CustomMessageTypeShare      = 6, //分享
 };
 
 

+ 3 - 0
NIMDemo/NIMDemo/Classes/Sections/Session/Model/Object/NTESSessionMsgConverter.h

@@ -14,6 +14,7 @@
 @class NTESChartletAttachment;
 @class NTESWhiteboardAttachment;
 @class NTESGiftAttachment;
+@class NTESShareAttachment;
 
 @interface NTESSessionMsgConverter : NSObject
 
@@ -43,4 +44,6 @@
 
 + (NIMMessage*)msgWithGift:(NTESGiftAttachment *)attachment;
 
++ (NIMMessage*)msgWithShare:(NTESShareAttachment *)attachment;
+
 @end

+ 11 - 0
NIMDemo/NIMDemo/Classes/Sections/Session/Model/Object/NTESSessionMsgConverter.m

@@ -13,6 +13,7 @@
 #import "NTESChartletAttachment.h"
 #import "NTESWhiteboardAttachment.h"
 #import "NTESGiftAttachment.h"
+#import "NTESShareAttachment.h"
 
 
 @implementation NTESSessionMsgConverter
@@ -177,4 +178,14 @@
     return message;
 }
 
++ (NIMMessage*)msgWithShare:(NTESShareAttachment *)attachment
+{
+    NIMMessage *message               = [[NIMMessage alloc] init];
+    NIMCustomObject *customObject     = [[NIMCustomObject alloc] init];
+    customObject.attachment           = attachment;
+    message.messageObject             = customObject;
+    message.apnsContent = @"发来分享信息";
+    return message;
+}
+
 @end

+ 20 - 0
NIMDemo/NIMDemo/Classes/Sections/Session/Model/Object/NTESShareAttachment.h

@@ -0,0 +1,20 @@
+//
+//  NTESShareAttachment.h
+//  NIMDemo
+//
+//  Created by Fenix Wang on 2017/8/9.
+//  Copyright © 2017年 Netease. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+#import "NTESCustomAttachmentDefines.h"
+
+@interface NTESShareAttachment : NSObject<NIMCustomAttachment,NTESCustomAttachmentInfo>
+
+@property (nonatomic, strong) NSString *tradeId;
+@property (nonatomic, strong) NSString *info;
+@property (nonatomic, strong) NSString *thumb;
+
+@property (nonatomic, strong) UITextView *showTextView;
+
+@end

+ 79 - 0
NIMDemo/NIMDemo/Classes/Sections/Session/Model/Object/NTESShareAttachment.m

@@ -0,0 +1,79 @@
+//
+//  NTESShareAttachment.m
+//  NIMDemo
+//
+//  Created by Fenix Wang on 2017/8/9.
+//  Copyright © 2017年 Netease. All rights reserved.
+//
+
+#import "NTESShareAttachment.h"
+#import "UIView+NTES.h"
+
+@implementation NTESShareAttachment
+
+- (NSString *)encodeAttachment
+{
+    NSDictionary *dict = @{CMType : @(CustomMessageTypeShare),
+                           CMData : @{CMValue:self.info,
+                                      CMURL:self.thumb,
+                                      @"tradeId":self.tradeId}};
+    NSData *data = [NSJSONSerialization dataWithJSONObject:dict
+                                                   options:0
+                                                     error:nil];
+    NSString *content = nil;
+    if (data) {
+        content = [[NSString alloc] initWithData:data
+                                        encoding:NSUTF8StringEncoding];
+    }
+    return content;
+}
+
+
+- (NSString *)cellContent:(NIMMessage *)message{
+    return @"NTESSessionShareContentView";
+}
+
+
+- (CGSize)contentSize:(NIMMessage *)message cellWidth:(CGFloat)width{
+    
+    float imageWidth = 80 + 5 * 2;
+    self.showTextView.width = width - 80 - imageWidth;
+    [self.showTextView sizeToFit];
+    CGSize size = self.showTextView.contentSize;
+    size.width += imageWidth;
+    size.height = MAX(size.height, imageWidth);
+    return size;
+}
+
+- (UIEdgeInsets)contentViewInsets:(NIMMessage *)message
+{
+    if (message.session.sessionType == NIMSessionTypeChatroom)
+    {
+        CGFloat bubbleMarginTopForImage  = 15.f;
+        CGFloat bubbleMarginLeftForImage = 12.f;
+        return  UIEdgeInsetsMake(bubbleMarginTopForImage,bubbleMarginLeftForImage,0,0);
+    }
+    else
+    {
+        CGFloat bubbleMarginForImage    = 3.f;
+        CGFloat bubbleArrowWidthForImage = 5.f;
+        if (message.isOutgoingMsg) {
+            return  UIEdgeInsetsMake(bubbleMarginForImage,bubbleMarginForImage,bubbleMarginForImage,bubbleMarginForImage + bubbleArrowWidthForImage);
+        }else{
+            return  UIEdgeInsetsMake(bubbleMarginForImage,bubbleMarginForImage + bubbleArrowWidthForImage, bubbleMarginForImage,bubbleMarginForImage);
+        }
+    }
+}
+
+- (UITextView *)showTextView
+{
+    if (_showTextView == nil)
+    {
+        _showTextView = [[UITextView alloc] init];
+        _showTextView.font = [UIFont systemFontOfSize:15];
+        _showTextView.text = self.info;
+    }
+    return _showTextView;
+}
+
+@end

+ 13 - 0
NIMDemo/NIMDemo/Classes/Sections/Session/View/SessionCell/SessionContentView/NTESSessionShareContentView.h

@@ -0,0 +1,13 @@
+//
+//  NTESSessionShareContentView.h
+//  NIMDemo
+//
+//  Created by Fenix Wang on 2017/8/9.
+//  Copyright © 2017年 Netease. All rights reserved.
+//
+
+#import "NIMSessionMessageContentView.h"
+
+@interface NTESSessionShareContentView : NIMSessionMessageContentView
+
+@end

+ 106 - 0
NIMDemo/NIMDemo/Classes/Sections/Session/View/SessionCell/SessionContentView/NTESSessionShareContentView.m

@@ -0,0 +1,106 @@
+//
+//  NTESSessionShareContentView.m
+//  NIMDemo
+//
+//  Created by Fenix Wang on 2017/8/9.
+//  Copyright © 2017年 Netease. All rights reserved.
+//
+
+#import "NTESSessionShareContentView.h"
+#import "NTESShareAttachment.h"
+#import "UIImageView+WebCache.h"
+
+@interface NTESSessionShareContentView()
+
+@property (nonatomic, strong, readwrite) UIImageView *iconView;
+@property (nonatomic, strong, readwrite) UITextView *textView;
+@property (nonatomic, assign) float imageSize;
+@property (nonatomic, assign) float padding;
+
+@end
+
+@implementation NTESSessionShareContentView
+
+- (instancetype)initSessionMessageContentView{
+    self = [super initSessionMessageContentView];
+    if (self) {
+        self.opaque = YES;
+        
+        _imageSize = 80;
+        _padding = 5;
+        
+        _iconView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, _imageSize, _imageSize)];
+        [_iconView setImage:[UIImage imageNamed:@"交易帖详情---更多_03"]];
+        [self addSubview:_iconView];
+        
+        _textView  = [[UITextView alloc] initWithFrame:CGRectZero];
+        _textView.backgroundColor = UIColor.clearColor;
+        _textView.font = [UIFont systemFontOfSize:15];
+        _textView.userInteractionEnabled = NO;
+        [self addSubview:_textView];
+    }
+    return self;
+}
+
+
+- (void)refresh:(NIMMessageModel *)data{
+    [super refresh:data];
+    NIMCustomObject *customObject = (NIMCustomObject*)data.message.messageObject;
+    id attachment = customObject.attachment;
+    if ([attachment isKindOfClass:[NTESShareAttachment class]]) {
+        
+        NTESShareAttachment *at = (NTESShareAttachment *)attachment;
+        if(data.message.isOutgoingMsg)
+        {
+            _textView.textColor = UIColor.whiteColor;
+        }
+        else
+        {
+            _textView.textColor = UIColor.blackColor;
+        }
+        self.textView.text = at.info;
+        if(at.thumb.length)
+        {
+            NSURL *url = [NSURL URLWithString:at.thumb];
+            [self.iconView sd_setImageWithURL:url placeholderImage:[UIImage imageNamed:@"交易帖详情---更多_03"]];
+        }
+        [self.textView sizeToFit];
+    }
+}
+
+- (void)layoutSubviews{
+    [super layoutSubviews];
+    UIEdgeInsets contentInsets = self.model.contentViewInsets;
+    CGSize contentSize = self.model.contentSize;
+    
+    
+    CGRect imageViewFrame = CGRectMake(contentInsets.left, contentInsets.top, contentSize.width, contentSize.height);
+    imageViewFrame.origin.x += _imageSize + _padding;
+    imageViewFrame.size.width -= _imageSize + _padding;
+    self.textView.frame  = imageViewFrame;
+    
+    self.iconView.frame = CGRectMake(contentInsets.left+5, contentInsets.top+5, _imageSize, _imageSize);
+    
+    CALayer *maskLayer = [CALayer layer];
+    maskLayer.cornerRadius = 13.0;
+    maskLayer.backgroundColor = [UIColor blackColor].CGColor;
+    maskLayer.frame = self.textView.bounds;
+    self.textView.layer.mask = maskLayer;
+}
+
+- (UIImage *)chatBubbleImageForState:(UIControlState)state outgoing:(BOOL)outgoing{
+    if (self.model.message.session.sessionType == NIMSessionTypeChatroom) {
+        return nil;
+    }
+    return [super chatBubbleImageForState:state outgoing:outgoing];
+}
+
+- (void)onTouchUpInside:(id)sender
+{
+    NIMKitEvent *event = [[NIMKitEvent alloc] init];
+    event.eventName = NIMKitEventNameTapContent;
+    event.messageModel = self.model;
+    [self.delegate onCatchEvent:event];
+}
+
+@end

+ 7 - 0
NIMDemo/NIMDemo/Classes/Sections/Session/ViewController/NTESSessionLocalHistoryViewController.m

@@ -12,6 +12,7 @@
 #import "NTESSearchLocalHistoryObject.h"
 #import "NTESBundleSetting.h"
 #import "UIView+NTES.h"
+#import "NTESSessionViewController.h"
 
 #define EntranceCellIdentity @"entrance"
 #define EntranceCellHeight   45
@@ -175,6 +176,12 @@
         [self.searchController setActive:NO];
         [self showSearchData:option loadMore:YES];
     }
+    else if(object.type == SearchLocalHistoryTypeContent)
+    {
+        NTESSessionViewController *sessionVC = [[NTESSessionViewController alloc] initWithSession:_session];
+        sessionVC.scrollToMessage = object.message;
+        [self.navigationController pushViewController:sessionVC animated:YES];
+    }
 }
 
 #pragma mark - Action

+ 2 - 0
NIMDemo/NIMDemo/Classes/Sections/Session/ViewController/NTESSessionViewController.h

@@ -17,4 +17,6 @@
 
 - (void)handleGiftMessage:(NTESGiftAttachment *)giftAttachment;
 
+
+
 @end

+ 113 - 16
NIMDemo/NIMDemo/Classes/Sections/Session/ViewController/NTESSessionViewController.m

@@ -62,6 +62,10 @@
 #import "NIMInputView.h"
 #import "CityManager.h"
 #import "ChatConfigViewController.h"
+#import "TradeDetailViewController.h"
+#import "NTESShareAttachment.h"
+#import "HttpRequest.h"
+#import "User.h"
 
 
 @interface NTESSessionViewController ()
@@ -85,6 +89,8 @@ NIMSessionDelegate>
 @property (nonatomic,strong)    NTESFPSLabel *fpsLabel;
 @property (nonatomic,strong)    NIMKitMediaFetcher *mediaFetcher;
 
+@property (nonatomic,strong)    GiftTopBarItem *systemMsgItem;
+@property (nonatomic,strong)    UIView         *giftItemContainer;
 @property (nonatomic,strong)    GiftTopBarItem *giftItem1;
 @property (nonatomic,strong)    GiftTopBarItem *giftItem2;
 @property (nonatomic,strong)    UIView         *giftMovieContainer;
@@ -92,6 +98,7 @@ NIMSessionDelegate>
 @property (nonatomic,strong)    NSTimer        *timer;
 
 @property (nonatomic,assign)    BOOL           displayed;
+@property (nonatomic,assign)    BOOL           fetchingSystemMsg;
 
 @end
 
@@ -142,13 +149,30 @@ NIMSessionDelegate>
     
     
     self.sessionInputView.giftContainer.delegate = self;
+    self.sessionInputView.tabCount = 5;
+    if(![[User sharedInfo] hasGiftToSend])
+    {
+        if(self.session.sessionType == NIMSessionTypeP2P || ![[User sharedInfo] isSystemTeam:self.session.sessionId])
+        {
+            self.sessionInputView.tabCount = 4;
+        }
+    }
+    
+    _systemMsgItem = [[GiftTopBarItem alloc] initWithFrame:CGRectMake(0, 64, self.view.width, 40)];
+    _systemMsgItem.hidden = YES;
+    [self.view addSubview:_systemMsgItem];
+    
+    
     
-    _giftItem1 = [[GiftTopBarItem alloc] initWithFrame:CGRectMake(0, 64, self.view.width, 40)];
+    _giftItemContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 64, self.view.width, 80)];
+    [self.view addSubview:_giftItemContainer];
+    
+    _giftItem1 = [[GiftTopBarItem alloc] initWithFrame:CGRectMake(0, 0, self.view.width, 40)];
     _giftItem1.hidden = YES;
-    [self.view addSubview:_giftItem1];
+    [_giftItemContainer addSubview:_giftItem1];
     _giftItem2 = [[GiftTopBarItem alloc] initWithFrame:CGRectMake(0, _giftItem1.bottom-5, self.view.width, 40)];
     _giftItem2.hidden = YES;
-    [self.view addSubview:_giftItem2];
+    [_giftItemContainer addSubview:_giftItem2];
     
     
     _giftMovieContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.width, self.view.height)];
@@ -165,7 +189,7 @@ NIMSessionDelegate>
     [self.view bringSubviewToFront:self.sessionInputView];
     [self.view bringSubviewToFront:self.sessionInputView.tabContainer];
     
-    _timer = [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(updateGiftTopItem) userInfo:nil repeats:YES];
+    _timer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(updateGiftTopItem) userInfo:nil repeats:YES];
     
     
     self.sessionInputView.giftContainer.tradeContainer.delegate = self;
@@ -203,9 +227,10 @@ NIMSessionDelegate>
         giftInput.supplyBtn.hidden = !isSystemTeam;
         giftInput.demandBtn.hidden = !isSystemTeam;
         
+        NIMTeam *team = [[NIMSDK sharedSDK].teamManager teamById:self.session.sessionId];
+        
         if(isSystemTeam)
         {
-            NIMTeam *team = [[NIMSDK sharedSDK].teamManager teamById:self.session.sessionId];
             NSString *teamName = team.teamName;
             TradePriorityType priorityType = [[CityManager shared] tradePriorityTypeByTeamName:teamName];
             NSMutableArray *priorityItems = [[NSMutableArray alloc] init];
@@ -220,6 +245,21 @@ NIMSessionDelegate>
             
             [giftInput.tradeContainer fillItemData:priorityItems];
         }
+        
+        __weak typeof(self) wself = self;
+        [[NIMSDK sharedSDK].teamManager fetchTeamMembers:team.teamId completion:^(NSError * _Nullable error, NSArray<NIMTeamMember *> * _Nullable members) {
+            NSMutableArray *userIds = [[NSMutableArray alloc] init];
+            for(NIMTeamMember *member in members)
+            {
+                [userIds addObject:member.userId];
+            }
+            [[HttpRequest shared] fetchAlias:userIds success:^{
+                [wself.tableView reloadData];
+            } failure:^{
+                
+            }];
+        }];
+        
     }
     else if(self.session.sessionType == NIMSessionTypeP2P)
     {
@@ -227,6 +267,9 @@ NIMSessionDelegate>
         giftInput.supplyBtn.hidden = YES;
         giftInput.demandBtn.hidden = YES;
     }
+    
+    
+    self.navigationController.interactivePopGestureRecognizer.enabled = NO;
 }
 
 - (void)viewDidAppear:(BOOL)animated{
@@ -242,6 +285,7 @@ NIMSessionDelegate>
     [[NIMSDK sharedSDK].mediaManager stopPlay];
     
     [_timer setFireDate:[NSDate distantFuture]];
+    self.navigationController.interactivePopGestureRecognizer.enabled = YES;
 }
 
 - (void)viewDidDisappear:(BOOL)animated{
@@ -573,9 +617,9 @@ NIMSessionDelegate>
 - (BOOL)onLongPressAvatar:(NSString *)userId{
     
     NSLog(@"onLongPressAvatar : %@", userId);
-    
+
     [self.sessionInputView addAtItem:userId];
-    
+
     return YES;
 }
 
@@ -636,6 +680,13 @@ NIMSessionDelegate>
 {
    //普通的自定义消息点击事件可以在这里做哦~
     NSLog(@"show custom message");
+    
+    NIMCustomObject *object = message.messageObject;
+    NTESShareAttachment *attachment = object.attachment;
+    
+    TradeDetailViewController *detailVC = [[TradeDetailViewController alloc] initWithTradeId:attachment.tradeId];
+    [self.navigationController pushViewController:detailVC animated:YES];
+    
 }
 
 
@@ -913,15 +964,15 @@ NIMSessionDelegate>
     UIButton *searchBtn = [UIButton buttonWithType:UIButtonTypeCustom];
     [searchBtn addTarget:self action:@selector(searchChatContent:) forControlEvents:UIControlEventTouchUpInside];
     [searchBtn setImage:[UIImage imageNamed:@"查找聊天内容_03"] forState:UIControlStateNormal];
-    [searchBtn sizeToFit];
     
-    UIBarButtonItem *searchItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSearch target:self action:@selector(searchChatContent:)];
-    UIBarButtonItem *deleteItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemTrash target:self action:@selector(deleteChatCache:)];
+    
+    
+    
 
     UIButton *deleteBtn = [UIButton buttonWithType:UIButtonTypeCustom];
-    [deleteBtn addTarget:self action:@selector(onTouchUpInfoBtn:) forControlEvents:UIControlEventTouchUpInside];
-    [deleteBtn setImage:[UIImage imageNamed:@"icon_session_info_normal"] forState:UIControlStateNormal];
-    [deleteBtn sizeToFit];
+    [deleteBtn addTarget:self action:@selector(deleteChatCache:) forControlEvents:UIControlEventTouchUpInside];
+    [deleteBtn setImage:[UIImage imageNamed:@"聊天-_03(2)"] forState:UIControlStateNormal];
+    [deleteBtn setFrame:CGRectMake(0, 0, 30, 30)];
     
     UIButton *chatConfigBtn = [UIButton buttonWithType:UIButtonTypeCustom];
     [chatConfigBtn addTarget:self action:@selector(onTouchChatConfig:) forControlEvents:UIControlEventTouchUpInside];
@@ -929,16 +980,19 @@ NIMSessionDelegate>
     [chatConfigBtn setSize:CGSizeMake(30, 30)];
     UIBarButtonItem *chatConfigItem = [[UIBarButtonItem alloc] initWithCustomView:chatConfigBtn];
     
-    //UIBarButtonItem *searchItem = [[UIBarButtonItem alloc] initWithCustomView:searchBtn];
-    //UIBarButtonItem *deleteItem = [[UIBarButtonItem alloc] initWithCustomView:deleteBtn];
     
     
+    UIBarButtonItem *searchItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSearch target:self action:@selector(searchChatContent:)];
+    //UIBarButtonItem *deleteItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemTrash target:self action:@selector(deleteChatCache:)];
+    
+    //UIBarButtonItem *searchItem = [[UIBarButtonItem alloc] initWithCustomView:searchBtn];
+    UIBarButtonItem *deleteItem = [[UIBarButtonItem alloc] initWithCustomView:deleteBtn];
     
     
     if(self.session.sessionType == NIMSessionTypeTeam)
     {
         NIMTeam *team = [[NIMSDK sharedSDK].teamManager teamById:self.session.sessionId];
-        if(team && team.owner && [team.owner isEqualToString:@"10000"])
+        if(team && team.owner && [team.owner intValue] < 20000)
         {
             [self.navigationItem.titleView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(enterTeamCard:)]];
             self.navigationItem.rightBarButtonItems = @[deleteItem, searchItem];
@@ -1171,6 +1225,18 @@ NIMSessionDelegate>
         
         [_giftItem2 setHidden:YES];
     }
+    
+    if(!_systemMsgItem.isHidden)
+    {
+        _systemMsgItem.timeCount++;
+        if(_systemMsgItem.timeCount > hideTimeCount)
+        {
+            [_systemMsgItem setHidden:YES];
+            _giftItemContainer.top = _systemMsgItem.top;
+        }
+    }
+    
+    [self fetchSystemMsg];
 }
 
 
@@ -1179,6 +1245,37 @@ NIMSessionDelegate>
     [_giftMovieContainer setHidden:YES];
 }
 
+
+- (void)fetchSystemMsg
+{
+    if(_fetchingSystemMsg)
+        return;
+    
+    _fetchingSystemMsg = YES;
+    [[HttpRequest shared] lastSystemMsg:^(NSMutableDictionary * _Nullable data) {
+        
+        if(data)
+        {
+            int msgId = [[data objectForKey:@"id"] intValue];
+            if([User sharedInfo].lastSystemMsgId < msgId)
+            {
+                [User sharedInfo].lastSystemMsgId = msgId;
+                NSString *msg = [data objectForKey:@"msg"];
+                _systemMsgItem.timeCount = 0;
+                [_systemMsgItem setSystemInfo:msg];
+                _systemMsgItem.hidden = NO;
+                
+                _giftItemContainer.top = _systemMsgItem.bottom;
+            }
+        }
+        
+        _fetchingSystemMsg = NO;
+    } failure:^{
+        _fetchingSystemMsg = NO;
+    }];
+}
+
+
 - (void)inputTabSelected{
     [self hideGiftMovie:nil];
 }

+ 4 - 0
NIMDemo/NIMDemo/Classes/Sections/SessionList/ViewController/NTESSessionListViewController.m

@@ -20,6 +20,7 @@
 #import "NTESGiftAttachment.h"
 #import "NTESSessionUtil.h"
 #import "NTESPersonalCardViewController.h"
+#import "NTESShareAttachment.h"
 
 #define SessionListTitle @"云信 Demo"
 
@@ -282,6 +283,9 @@
         else if ([object.attachment isKindOfClass:[NTESGiftAttachment class]]) {
             text = @"[礼物]";
         }
+        else if ([object.attachment isKindOfClass:[NTESShareAttachment class]]) {
+            text = @"[分享]";
+        }
         else{
             text = @"[未知消息]";
         }

+ 16 - 13
NIMDemo/NIMDemo/Classes/Sections/Setting/UInfo/NTESAliasSettingViewController.m

@@ -11,6 +11,9 @@
 #import "NIMCommonTableData.h"
 #import "SVProgressHUD.h"
 #import "UIView+Toast.h"
+#import "HttpRequest.h"
+#import "User.h"
+#import "NIMKit.h"
 
 @interface NTESAliasSettingViewController()
 
@@ -43,7 +46,7 @@
     [self setUpNav];
     self.navigationItem.title = @"备注名";
     __weak typeof(self) wself = self;
-    self.alias = self.user.alias;
+    self.alias = [[NIMKit sharedKit] getAlias:self.user.userId] ? [[NIMKit sharedKit] getAlias:self.user.userId] : @"";
     [self buildData];
     self.delegator = [[NIMCommonTableDelegate alloc] initWithTableData:^NSArray *{
         return wself.data;
@@ -89,19 +92,19 @@
     }
     [SVProgressHUD show];
     __weak typeof(self) wself = self;
-    self.user.alias = self.alias;
-    [[NIMSDK sharedSDK].userManager updateUser:self.user completion:^(NSError *error) {
+    
+    [[HttpRequest shared] updateAlias:self.user.userId alias:self.alias success:^{
         [SVProgressHUD dismiss];
-        if (!error) {
-            [wself.navigationController.view makeToast:@"备注名设置成功"
-                         duration:2
-                         position:CSToastPositionCenter];
-            [wself.navigationController popViewControllerAnimated:YES];
-        }else{
-            [wself.view makeToast:@"备注名设置失败,请重试"
-                         duration:2
-                         position:CSToastPositionCenter];
-        }
+        [[NIMKit sharedKit] setAlias:wself.user.userId alias:wself.alias];
+        [wself.navigationController.view makeToast:@"备注名设置成功"
+                                          duration:2
+                                          position:CSToastPositionCenter];
+        [wself.navigationController popViewControllerAnimated:YES];
+    } failure:^{
+        [SVProgressHUD dismiss];
+        [wself.view makeToast:@"备注名设置失败,请重试"
+                     duration:2
+                     position:CSToastPositionCenter];
     }];
 }
 

+ 1 - 1
NIMDemo/NIMDemo/Classes/Sections/Setting/UInfo/NTESGenderSettingViewController.m

@@ -70,7 +70,7 @@
                                       ForbidSelect  : @(YES),
                                       },
                                   @{
-                                      Title         : @"其他",
+                                      Title         : @"保密",
                                       CellClass     : @"NTESSettingCheckCell",
                                       CellAction    : @"onTouchUnkownGenderCell:",
                                       RowHeight     : @(50),

+ 2 - 1
NIMDemo/NIMDemo/Classes/Util/NTESDemoConfig.m

@@ -29,7 +29,8 @@
     {
         _appKey = @"7b8c319e77664d91d28520b83840b221";
         _apiURL = @"https://app.netease.im/api";
-        _cerName= @"ENTERPRISE";
+        _cerName= @"sheishuopush";
+        //_cerName= @"sheishuopushdist";
     }
     return self;
 }

+ 1 - 1
NIMDemo/NIMDemo/Classes/Util/NTESUserUtil.m

@@ -21,7 +21,7 @@
             genderStr = @"女";
             break;
         case NIMUserGenderUnknown:
-            genderStr = @"未知";
+            genderStr = @"保密";
         default:
             break;
     }

+ 111 - 7
NIMDemo/NIMDemo/ContactViewController.m

@@ -13,21 +13,57 @@
 #import "HttpRequest.h"
 #import "ContactTableViewCell.h"
 #import "User.h"
+#import "UIView+NTES.h"
 
 @implementation ContactData
 @end
 
-@interface ContactViewController ()
+@interface ContactViewController ()<UISearchBarDelegate>
 
 @property (nonatomic, strong) NSMutableArray            *contactArr;
 @property (nonatomic, strong) NSMutableDictionary       *contactDict;
 
+@property (nonatomic, strong) UIView                    *authView;
+
+@property (nonatomic, strong) UISearchController    *searchController;
+@property (nonatomic, strong) NSMutableArray        *searchArr;
+
 @end
 
 @implementation ContactViewController
 
 - (void)viewDidLoad {
     [super viewDidLoad];
+    
+    _authView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.width, self.view.height)];
+    [self.view addSubview:_authView];
+    
+    float imageWidth = self.view.width - 40 * 2;
+    UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(40, 40, imageWidth, imageWidth)];
+    [imgView setImage:[UIImage imageNamed:@"开启通讯录_03"]];
+    [_authView addSubview:imgView];
+    
+    UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
+    btn.frame = CGRectMake(40, imgView.bottom + (_authView.height - imgView.bottom)/2 - 25, imageWidth, 50);
+    btn.layer.cornerRadius = 25;
+    btn.backgroundColor = User.orangeColor;
+    [btn setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
+    [btn setTitle:@"开启通讯录" forState:UIControlStateNormal];
+    [btn addTarget:self action:@selector(onTouchContactAuth:) forControlEvents:UIControlEventTouchUpInside];
+    [_authView addSubview:btn];
+    
+    
+    
+    _searchArr = [[NSMutableArray alloc] init];
+    
+    _searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
+    _searchController.hidesNavigationBarDuringPresentation = NO;
+    _searchController.searchBar.tintColor = UIColor.whiteColor;
+    _searchController.dimsBackgroundDuringPresentation = NO;
+    _searchController.searchBar.delegate = self;
+    [self.tableView setTableHeaderView:_searchController.searchBar];
+    
+    [self showContactAuth];
 }
 
 - (void)didReceiveMemoryWarning {
@@ -45,6 +81,44 @@
     [self requestAuthorizationAddressBook];
 }
 
+- (void)viewWillDisappear:(BOOL)animated
+{
+    [super viewWillDisappear:animated];
+    [self.searchController setActive:NO];
+}
+
+
+- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
+{
+    NSLog(@"textDidChange %@  %@", searchBar.text, searchText);
+    
+    if(searchText.length > 0)
+    {
+        [self.searchArr removeAllObjects];
+        
+        for(int i=0; i<_contactArr.count; i++)
+        {
+            ContactData *data = [_contactArr objectAtIndex:i];
+            if([[data.name lowercaseString] containsString:[searchText lowercaseString]])
+            {
+                [_searchArr addObject:data];
+            }
+        }
+    }
+    else
+    {
+        [self.searchArr removeAllObjects];
+    }
+    
+    [self.tableView reloadData];
+}
+
+- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
+{
+    [self.searchArr removeAllObjects];
+    [self.tableView reloadData];
+}
+
 - (void)requestAuthorizationAddressBook {
     // 判断是否授权
     ABAuthorizationStatus authorizationStatus = ABAddressBookGetAuthorizationStatus();
@@ -70,9 +144,12 @@
     if (authorizationStatus != kABAuthorizationStatusAuthorized) {
         
         NSLog(@"没有授权");
+        [self showContactAuth];
         return;
     }
     
+    [self hideContactAuth];
+    
     // 2. 获取所有联系人
     _contactArr = [[NSMutableArray alloc] init];
     _contactDict = [[NSMutableDictionary alloc] init];
@@ -93,6 +170,15 @@
         NSLog(@"--------------------------------------------------");
         NSLog(@"firstName=%@, lastName=%@", firstName, lastName);
         
+        if(!firstName)
+        {
+            firstName = @"";
+        }
+        if(!lastName)
+        {
+            lastName = @"";
+        }
+        
         ContactData *data = [[ContactData alloc] init];
         data.name = [NSString stringWithFormat:@"%@%@", lastName, firstName];
         
@@ -103,13 +189,17 @@
         for(int j=0; j<phoneCount; j++)
         {
             NSString * personPhone = (__bridge NSString*)ABMultiValueCopyValueAtIndex(phones, j);
+            personPhone = [personPhone stringByReplacingOccurrencesOfString:@" " withString:@""];
+            personPhone = [personPhone stringByReplacingOccurrencesOfString:@"-" withString:@""];
+            personPhone = [personPhone stringByReplacingOccurrencesOfString:@"+" withString:@""];
             [phoneArray addObject:personPhone];
             [mobiles addObject:personPhone];
             [_contactDict setValue:data forKey:personPhone];
         }
         
         data.phones = phoneArray;
-        [_contactArr addObject:data];
+        if(phoneArray.count > 0)
+            [_contactArr addObject:data];
     }
     
     if(mobiles.count > 0)
@@ -157,11 +247,9 @@
 
 #pragma mark - Table view data source
 
-- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
-    return 1;
-}
-
 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+    if(_searchArr.count)
+        return _searchArr.count;
     if(!_contactArr)
         return 0;
     return _contactArr.count;
@@ -171,11 +259,27 @@
 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
     
     ContactTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Contact"];
-    ContactData *data = [_contactArr objectAtIndex:indexPath.row];
+    ContactData *data = _searchArr.count > 0 ? [_searchArr objectAtIndex:indexPath.row] : [_contactArr objectAtIndex:indexPath.row];
     [cell setData:data];
     
     return cell;
 }
 
 
+
+- (void)showContactAuth{
+    _authView.hidden = NO;
+    _searchController.searchBar.hidden = YES;
+}
+
+- (void)hideContactAuth{
+    _authView.hidden = YES;
+    _searchController.searchBar.hidden = NO;
+}
+
+- (void)onTouchContactAuth:(id)sender{
+    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
+}
+
+
 @end

+ 4 - 3
NIMDemo/NIMDemo/CreateGroupViewController.m

@@ -19,6 +19,7 @@
 #import "AFNetworking/AFNetworking.h"
 #import "UIImage+NIM.h"
 #import "NIMAvatarImageView.h"
+#import "CityManager.h"
 
 @interface CreateGroupViewController ()
 <UIActionSheetDelegate,
@@ -138,7 +139,7 @@ UIActionSheet *_avatarActionSheet;
                 wself.avatarUrl = urlString;
                 [[SDWebImageManager sharedManager] saveImageToCache:imageForAvatarUpload forURL:[NSURL URLWithString:urlString]];
                 NSURL *avatarUrl = urlString.length? [NSURL URLWithString:urlString] : nil;
-                [wself.avatar nim_setImageWithURL:avatarUrl placeholderImage:[UIImage imageNamed:@"avatar_team"]];
+                [wself.avatar nim_setImageWithURL:avatarUrl placeholderImage:[User defaultTeamAvatar:nil]];
             }else{
                 [wself.view makeToast:@"图片上传失败,请重试"
                              duration:2
@@ -221,7 +222,7 @@ UIActionSheet *_avatarActionSheet;
 - (IBAction)createGroup:(id)sender {
 
     NSString *teamName = self.nickTextField.text;
-    if([[User sharedInfo] isSystemTeam:teamName])
+    if([[CityManager shared] isCityName:teamName])
     {
         UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"不能用地名作为群聊名称" message:nil delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
         [alert show];
@@ -234,7 +235,7 @@ UIActionSheet *_avatarActionSheet;
     option.name       = teamName;
     option.intro      = self.descTextView.text;
     option.type       = NIMTeamTypeAdvanced;
-    option.joinMode   = NIMTeamJoinModeNoAuth;
+    option.joinMode   = NIMTeamJoinModeNeedAuth;
     option.postscript = @"邀请你加入群组";
     if(![self.avatarUrl isEqualToString:@""] && self.avatarUrl != nil)
         option.avatarUrl = self.avatarUrl;

+ 13 - 0
NIMDemo/NIMDemo/ForgetTableViewController.h

@@ -0,0 +1,13 @@
+//
+//  ForgetTableViewController.h
+//  NIMDemo
+//
+//  Created by Fenix Wang on 2017/9/15.
+//  Copyright © 2017年 Netease. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface ForgetTableViewController : UITableViewController
+
+@end

+ 168 - 0
NIMDemo/NIMDemo/ForgetTableViewController.m

@@ -0,0 +1,168 @@
+//
+//  ForgetTableViewController.m
+//  NIMDemo
+//
+//  Created by Fenix Wang on 2017/9/15.
+//  Copyright © 2017年 Netease. All rights reserved.
+//
+
+#import "ForgetTableViewController.h"
+#import "User.h"
+#import "SVProgressHUD.h"
+#import "UIView+Toast.h"
+#import "HttpRequest.h"
+
+@interface ForgetTableViewController ()<UITextFieldDelegate>
+@property (weak, nonatomic) IBOutlet UITextField *mobileInput;
+@property (weak, nonatomic) IBOutlet UITextField *codeInput;
+@property (weak, nonatomic) IBOutlet UITextField *pwdInput;
+@property (weak, nonatomic) IBOutlet UITextField *confirmInput;
+@property (weak, nonatomic) IBOutlet UIButton *sendCodeBtn;
+
+@property (strong, nonatomic) NSTimer       *timer;
+@property (assign, nonatomic) int           maxWaitSec;
+@property (assign, nonatomic) int           currentWaitSec;
+
+@end
+
+@implementation ForgetTableViewController
+
+- (void)viewDidLoad {
+    [super viewDidLoad];
+    
+    _mobileInput.delegate = self;
+    _codeInput.delegate = self;
+    _pwdInput.delegate = self;
+    _confirmInput.delegate = self;
+    
+    _mobileInput.borderStyle = UITextBorderStyleNone;
+    _codeInput.borderStyle = UITextBorderStyleNone;
+    _pwdInput.borderStyle = UITextBorderStyleNone;
+    _confirmInput.borderStyle = UITextBorderStyleNone;
+    
+    
+    _maxWaitSec = 60;
+    _currentWaitSec = 0;
+    
+    _timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateSendCodeBtn) userInfo:nil repeats:YES];
+    [_timer setFireDate:[NSDate distantFuture]];
+    
+    [_sendCodeBtn setTitle:@"获取验证码" forState:UIControlStateNormal];
+    [_sendCodeBtn setTitleColor:User.greenColor forState:UIControlStateNormal];
+    [_sendCodeBtn setUserInteractionEnabled:YES];
+}
+
+- (void)didReceiveMemoryWarning {
+    [super didReceiveMemoryWarning];
+    // Dispose of any resources that can be recreated.
+}
+
+- (void)viewWillAppear:(BOOL)animated{
+    [super viewWillAppear:animated];
+    
+    [self.navigationItem setTitle:@"密码重置"];
+    
+    UIButton *submitBtn = [UIButton buttonWithType:UIButtonTypeCustom];
+    [submitBtn setTitle:@"提交" forState:UIControlStateNormal];
+    [submitBtn setTitleColor:UIColor.blackColor forState:UIControlStateNormal];
+    [submitBtn addTarget:self action:@selector(onTouchSubmit:) forControlEvents:UIControlEventTouchUpInside];
+    [submitBtn sizeToFit];
+    
+    UIBarButtonItem *rightItem = [[UIBarButtonItem alloc] initWithCustomView:submitBtn];
+    [self.navigationItem setRightBarButtonItems:@[rightItem]];
+}
+
+- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
+    
+    if ([string isEqualToString:@"\n"]) {
+        [textField resignFirstResponder];
+        return NO;
+    }
+    return YES;
+}
+
+- (void)reset{
+    _mobileInput.text = @"";
+    _codeInput.text = @"";
+    _pwdInput.text = @"";
+    _confirmInput.text = @"";
+}
+
+- (IBAction)onTouchSendCode:(id)sender {
+    
+    NSString *mobile = self.mobileInput.text;
+    
+    if(mobile.length < 11)
+    {
+        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"请正确填写手机号" message:nil delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
+        [alert show];
+        return;
+    }
+    
+    
+    [[HttpRequest shared] sendCode:mobile success:^{
+        
+    } failure:^{
+        
+    }];
+    
+    _currentWaitSec = 0;
+    [_sendCodeBtn setUserInteractionEnabled:NO];
+    [_sendCodeBtn setTitleColor:UIColor.lightGrayColor forState:UIControlStateNormal];
+    [_timer setFireDate:[NSDate distantPast]];
+}
+
+- (void)updateSendCodeBtn{
+    
+    _currentWaitSec++;
+    
+    if(_currentWaitSec >= _maxWaitSec)
+    {
+        [_sendCodeBtn setTitle:@"获取验证码" forState:UIControlStateNormal];
+        [_sendCodeBtn setTitleColor:User.greenColor forState:UIControlStateNormal];
+        [_sendCodeBtn setUserInteractionEnabled:YES];
+        [_timer setFireDate:[NSDate distantFuture]];
+    }
+    else
+    {
+        int displaySec = _maxWaitSec - _currentWaitSec;
+        _sendCodeBtn.titleLabel.text = [NSString stringWithFormat:@"%d秒后重新获取", displaySec];
+        [_sendCodeBtn setTitle:[NSString stringWithFormat:@"%d秒后重新获取", displaySec] forState:UIControlStateNormal];
+    }
+}
+
+- (void)onTouchSubmit:(id)sender{
+    NSString *mobile = _mobileInput.text;
+    NSString *code = _codeInput.text;
+    NSString *pwd = _pwdInput.text;
+    NSString *confirm = _confirmInput.text;
+    
+    int max = 12;
+    
+    if(![pwd isEqualToString:confirm])
+    {
+        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"密码与确认密码不一致" message:nil delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
+        [alert show];
+        return;
+    }
+    
+    if(pwd.length < Password_Min_Length || pwd.length > max)
+    {
+        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"密码长度不正确" message:nil delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
+        [alert show];
+        return;
+    }
+    
+    [SVProgressHUD show];
+    __weak typeof(self) wself = self;
+    [[HttpRequest shared] forgetPassword:mobile code:code password:pwd success:^{
+        [SVProgressHUD dismiss];
+        [wself.view makeToast:@"密码重置成功" duration:2 position:CSToastPositionCenter];
+        [wself reset];
+    } failure:^{
+        [SVProgressHUD dismiss];
+        [wself.view makeToast:@"密码重置失败,请重试。" duration:2 position:CSToastPositionCenter];
+    }];
+}
+
+@end

+ 5 - 2
NIMDemo/NIMDemo/FriendListViewController.h

@@ -10,10 +10,13 @@
 #import "NTESGroupedDataCollection.h"
 
 @interface GroupedContacts : NTESGroupedDataCollection
-
+- (instancetype)initWithMembers:(NSMutableArray *)members;
 @end
 
 
-@interface FriendListViewController : UITableViewController
+@interface FriendListViewController : UIViewController<UITableViewDelegate, UITableViewDataSource>
+
+@property (weak, nonatomic) IBOutlet UITableView    *tableView;
+@property (nonatomic, strong) NSMutableArray        *requestArr;
 
 @end

+ 108 - 16
NIMDemo/NIMDemo/FriendListViewController.m

@@ -16,6 +16,7 @@
 #import "UIView+Toast.h"
 #import "ContactViewController.h"
 #import "HttpRequest.h"
+#import "NTESSessionViewController.h"
 
 @implementation GroupedContacts
 
@@ -46,10 +47,15 @@
 
 
 @interface FriendListViewController ()<NTESContactUtilCellDelegate,
-NIMContactDataCellDelegate>
+NIMContactDataCellDelegate, UISearchBarDelegate>
 
+
+
+@property (weak, nonatomic) IBOutlet UITableView    *tableViewComponent;
+@property (nonatomic, strong) UISearchController    *searchController;
 @property (nonatomic, strong) GroupedContacts       *contacts;
-@property (nonatomic, strong) NSMutableArray        *requestArr;
+
+@property (nonatomic, strong) NSMutableArray        *searchArr;
 
 @end
 
@@ -58,18 +64,20 @@ NIMContactDataCellDelegate>
 - (void)viewDidLoad {
     [super viewDidLoad];
     
+    _searchArr = [[NSMutableArray alloc] init];
+    
+    _searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
+    //_searchController.searchBar.barTintColor = User.orangeColor;
+    _searchController.hidesNavigationBarDuringPresentation = NO;
+    _searchController.searchBar.tintColor = UIColor.whiteColor;
+    //_searchController.delegate = self;
+    _searchController.dimsBackgroundDuringPresentation = NO;
+    _searchController.searchBar.delegate = self;
+    [self.view addSubview:_searchController.searchBar];
+    
     __weak typeof(self) wself = self;
     [[User sharedInfo] requestFollowList:^{
-        
-        [[HttpRequest shared] requestFriendList:^(NSMutableArray<FriendRequestData *> * _Nullable dataArr) {
-            
-            wself.requestArr = dataArr;
-            [wself fetchUserInfos];
-            
-        } failure:^{
-            [wself fetchUserInfos];
-        }];
-        
+        [wself fetchUserInfos];
     }];
 }
 
@@ -93,6 +101,7 @@ NIMContactDataCellDelegate>
         [infoArr addObject:contact];
     }
     
+    NSInteger systemCount = [[[NIMSDK sharedSDK] systemNotificationManager] allUnreadCount];
     _contacts = [[GroupedContacts alloc] initWithMembers:infoArr];
     
     NSString *contactCellUtilIcon   = @"icon";
@@ -109,7 +118,12 @@ NIMContactDataCellDelegate>
            contactCellUtilIcon:@"通讯录_03",
            contactCellUtilTitle:@"新的朋友",
            contactCellUtilStory:@"FriendRequest",
-           contactCellUtilBadge:@(_requestArr.count)
+           contactCellUtilBadge:@(_requestArr.count+systemCount)
+           },
+       @{
+           contactCellUtilIcon:@"通讯录_新的关注",
+           contactCellUtilTitle:@"我的粉丝",
+           contactCellUtilStory:@"BeFollowed"
            },
        @{
            contactCellUtilIcon:@"通讯录_06",
@@ -161,19 +175,80 @@ NIMContactDataCellDelegate>
     [self prepareData];
 }
 
+- (void)viewWillDisappear:(BOOL)animated
+{
+    [super viewWillDisappear:animated];
+    [self.searchController setActive:NO];
+}
+
+
+- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
+{
+    NSLog(@"textDidChange %@  %@", searchBar.text, searchText);
+    
+    if(searchText.length > 0)
+    {
+        [self.searchArr removeAllObjects];
+        for(int i=0; i<_contacts.groupCount; i++)
+        {
+            NSArray *members = [_contacts membersOfGroup:i];
+            for(int j=0; j<members.count; j++)
+            {
+                id member = [members objectAtIndex:j];
+                if(![member isKindOfClass:[NTESContactDataMember class]])
+                {
+                    continue;
+                }
+                NTESContactDataMember *dataMember = member;
+                if([dataMember.info.showName containsString:searchText])
+                {
+                    [_searchArr addObject:member];
+                }
+            }
+        }
+    }
+    else
+    {
+        [self.searchArr removeAllObjects];
+    }
+    
+    [self.tableView reloadData];
+}
+
+- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
+{
+    [self.searchArr removeAllObjects];
+    [self.tableView reloadData];
+}
+
+
 #pragma mark - Table view data source
 
 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
+    if(_searchArr.count)
+        return _searchArr.count;
     return [_contacts memberCountOfGroup:section];
 }
 
 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
+    if(_searchArr.count)
+        return 1;
     return [_contacts groupCount];
 }
 
 
 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
-    id contactItem = [_contacts memberOfIndex:indexPath];
+    
+    id contactItem = nil;
+    if(_searchArr.count)
+    {
+        contactItem = [_searchArr objectAtIndex:indexPath.row];
+    }
+    else
+    {
+        contactItem = [_contacts memberOfIndex:indexPath];
+    }
+        
     NSString * cellId = [contactItem reuseId];
     UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:cellId];
     if (!cell) {
@@ -197,7 +272,16 @@ NIMContactDataCellDelegate>
 
 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
     [tableView deselectRowAtIndexPath:indexPath animated:YES];
-    id<NTESContactItem> contactItem = (id<NTESContactItem>)[_contacts memberOfIndex:indexPath];
+    
+    id<NTESContactItem> contactItem = nil;
+    if(_searchArr.count)
+    {
+        contactItem = [_searchArr objectAtIndex:indexPath.row];
+    }
+    else
+    {
+        contactItem = (id<NTESContactItem>)[_contacts memberOfIndex:indexPath];
+    }
     if ([contactItem respondsToSelector:@selector(selName)] && [contactItem selName].length) {
         SEL sel = NSSelectorFromString([contactItem selName]);
         SuppressPerformSelectorLeakWarning([self performSelector:sel withObject:nil]);
@@ -229,10 +313,14 @@ NIMContactDataCellDelegate>
 }
 
 - (NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
+    if(_searchArr.count)
+        return nil;
     return [_contacts titleOfGroup:section];
 }
 
 - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
+    if(_searchArr.count)
+        return nil;
     return _contacts.sortedGroupTitles;
 }
 
@@ -242,14 +330,18 @@ NIMContactDataCellDelegate>
 
 
 
+
 #pragma mark - NIMContactDataCellDelegate
 - (void)onPressAvatar:(NSString *)memberId{
+//    NIMSession *session = [NIMSession session:memberId type:NIMSessionTypeP2P];
+//    NTESSessionViewController *vc = [[NTESSessionViewController alloc] initWithSession:session];
+//    [self.navigationController pushViewController:vc animated:YES];
     [User showUserInfo:memberId viewController:self];
 }
 
 #pragma mark - NTESContactUtilCellDelegate
 - (void)onPressUtilImage:(NSString *)content{
-    [self.view makeToast:[NSString stringWithFormat:@"点我干嘛 我是<%@>",content] duration:2.0 position:CSToastPositionCenter];
+    //[self.view makeToast:[NSString stringWithFormat:@"点我干嘛 我是<%@>",content] duration:2.0 position:CSToastPositionCenter];
 }
 
 @end

+ 3 - 3
NIMDemo/NIMDemo/FriendRequestTableViewCell.h

@@ -11,8 +11,8 @@
 
 @protocol FriendRequestAction <NSObject>
 
-- (void)friendRequestAccept:(FriendRequestData *)data;
-- (void)friendRequestDelete:(NSString *)requestId;
+- (void)friendRequestAccept:(id)data;
+- (void)friendRequestDelete:(id)data;
 
 @end
 
@@ -20,6 +20,6 @@
 
 @property (nonatomic, weak) id<FriendRequestAction>             delegate;
 
-- (void)setData:(FriendRequestData *)data;
+- (void)setData:(id)data;
 
 @end

+ 86 - 8
NIMDemo/NIMDemo/FriendRequestTableViewCell.m

@@ -19,7 +19,7 @@
 @property (weak, nonatomic) IBOutlet UIButton *btn;
 
 @property (nonatomic, strong) NIMAvatarImageView *avatar;
-@property (nonatomic, strong) FriendRequestData *data;
+@property (nonatomic, strong) id data;
 @end
 
 @implementation FriendRequestTableViewCell
@@ -43,7 +43,7 @@
     // Configure the view for the selected state
 }
 
-- (void)setData:(FriendRequestData *)data{
+- (void)setData:(id)data{
     _data = data;
     
     if(!_avatarContainer || !data)
@@ -58,15 +58,93 @@
     }
     
     __weak typeof(self) wself = self;
-    [[NIMSDK sharedSDK].userManager fetchUserInfos:@[data.userId] completion:^(NSArray<NIMUser *> * _Nullable users, NSError * _Nullable error) {
-        NIMUser *user = [users objectAtIndex:0];
+    if([data isKindOfClass:[FriendRequestData class]])
+    {
+        FriendRequestData *friendRequestData = data;
+        NIMUser *user = [[NIMSDK sharedSDK].userManager userInfo:friendRequestData.userId];
         NSURL *url = user.userInfo.avatarUrl ? [NSURL URLWithString:user.userInfo.avatarUrl] : nil;
         [wself.avatar nim_setImageWithURL:url placeholderImage:User.defaultUserAvatar];
         
         wself.nameLabel.text = [[User sharedInfo] getUserName:user];
-    }];
-    
-    _descLabel.text = data.msg;
+        _descLabel.text = friendRequestData.msg;
+        
+        _btn.hidden = NO;
+    }
+    else if([data isKindOfClass:[NIMSystemNotification class]])
+    {
+        NIMSystemNotification *systemData = data;
+        NIMKitInfo *sourceMember = [[NIMKit sharedKit] infoByUser:systemData.sourceID option:nil];
+        NIMSystemNotificationType type = systemData.type;
+        NSString *avatarUrlString = sourceMember.avatarUrlString;
+        NSURL *url;
+        if (avatarUrlString.length) {
+            url = [NSURL URLWithString:avatarUrlString];
+        }
+        [self.avatar nim_setImageWithURL:url placeholderImage:User.defaultUserAvatar];
+        
+        NIMUser *nimUser = [[NIMSDK sharedSDK].userManager userInfo:systemData.sourceID];
+        wself.nameLabel.text = [[User sharedInfo] getUserName:nimUser];
+        
+        switch (type) {
+            case NIMSystemNotificationTypeTeamApply:
+            {
+                NIMTeam *team = [[NIMSDK sharedSDK].teamManager teamById:systemData.targetID];
+                self.descLabel.text = [NSString stringWithFormat:@"申请加入群 %@ %@", team.teamName, systemData.postscript ? systemData.postscript : @""];
+                _btn.hidden = NO;
+            }
+                break;
+            case NIMSystemNotificationTypeTeamApplyReject:
+            {
+                NIMTeam *team = [[NIMSDK sharedSDK].teamManager teamById:systemData.targetID];
+                self.descLabel.text = [NSString stringWithFormat:@"群 %@ 拒绝你加入", team.teamName];
+                _btn.hidden = YES;
+            }
+                break;
+            case NIMSystemNotificationTypeTeamInvite:
+            {
+                NIMTeam *team = [[NIMSDK sharedSDK].teamManager teamById:systemData.targetID];
+                self.descLabel.text = [NSString stringWithFormat:@"群 %@ 邀请你加入", team.teamName];
+                _btn.hidden = NO;
+            }
+                break;
+            case NIMSystemNotificationTypeTeamIviteReject:
+            {
+                NIMTeam *team = [[NIMSDK sharedSDK].teamManager teamById:systemData.targetID];
+                self.descLabel.text = [NSString stringWithFormat:@"拒绝了群 %@ 邀请", team.teamName];
+                _btn.hidden = YES;
+            }
+                break;
+            case NIMSystemNotificationTypeFriendAdd:
+            {
+                NSString *text = @"未知请求";
+                id object = systemData.attachment;
+                if ([object isKindOfClass:[NIMUserAddAttachment class]]) {
+                    NIMUserOperation operation = [(NIMUserAddAttachment *)object operationType];
+                    switch (operation) {
+                        case NIMUserOperationAdd:
+                            text = @"已添加你为好友";
+                            break;
+                        case NIMUserOperationRequest:
+                            text = @"请求添加你为好友";
+                            break;
+                        case NIMUserOperationVerify:
+                            text = @"通过了你的好友请求";
+                            break;
+                        case NIMUserOperationReject:
+                            text = @"拒绝了你的好友请求";
+                            break;
+                        default:
+                            break;
+                    }
+                }
+                self.descLabel.text = text;
+            }
+                break;
+            default:
+                break;
+        }
+
+    }
 }
 
 - (void)longGesturePress:(UIGestureRecognizer*)gestureRecognizer
@@ -74,7 +152,7 @@
     if ([gestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]] &&
         gestureRecognizer.state == UIGestureRecognizerStateBegan) {
         if (self.delegate && [self.delegate respondsToSelector:@selector(friendRequestDelete:)]) {
-            [self.delegate friendRequestDelete:_data.requestId];
+            [self.delegate friendRequestDelete:_data];
         }
     }
 }

+ 381 - 36
NIMDemo/NIMDemo/FriendRequestViewController.m

@@ -12,14 +12,21 @@
 #import "FriendRequestTableViewCell.h"
 #import "HttpRequest.h"
 #import "UIView+Toast.h"
+#import "NTESSystemNotificationCell.h"
+#import "User.h"
 
 @implementation FriendRequestData
 
 @end
 
-@interface FriendRequestViewController ()<FriendRequestAction>
+@interface FriendRequestViewController ()<FriendRequestAction, UISearchBarDelegate>
 
 @property (nonatomic, strong) NSMutableArray            *dataArr;
+@property (nonatomic, strong) NSMutableArray            *systemArr;
+
+@property (nonatomic, strong) UISearchController    *searchController;
+@property (nonatomic, strong) NSMutableArray        *searchArr;
+
 
 @end
 
@@ -27,6 +34,60 @@
 
 - (void)viewDidLoad {
     [super viewDidLoad];
+    
+    _systemArr = [[NSMutableArray alloc] init];
+    
+    id<NIMSystemNotificationManager> systemNotificationManager = [[NIMSDK sharedSDK] systemNotificationManager];
+    NSArray *notifications = [systemNotificationManager fetchSystemNotifications:nil
+                                                                           limit:20];
+    
+    NSMutableArray *ids = [[NSMutableArray alloc] init];
+    if ([notifications count])
+    {
+        for(int i=0; i<notifications.count; i++)
+        {
+            NIMSystemNotification *notification = [notifications objectAtIndex:i];
+            if(notification.type == NIMSystemNotificationTypeFriendAdd)
+            {
+                [self deleteNotification:notification];
+                continue;
+            }
+            
+            BOOL found = NO;
+            for(int j=0; j<_systemArr.count; j++)
+            {
+                NIMSystemNotification *existNotification = [_systemArr objectAtIndex:j];
+                if(existNotification.type == notification.type &&
+                   [existNotification.targetID isEqualToString:notification.targetID] &&
+                   [existNotification.sourceID isEqualToString:notification.sourceID])
+                {
+                    [self deleteNotification:notification];
+                    found = YES;
+                    break;
+                }
+            }
+            
+            if(!found)
+            {
+                [_systemArr addObject:notification];
+                [ids addObject:notification.sourceID];
+            }
+        }
+    }
+    
+    [[NIMSDK sharedSDK].userManager fetchUserInfos:ids completion:^(NSArray<NIMUser *> * _Nullable users, NSError * _Nullable error) {
+        [self.tableView reloadData];
+    }];
+    
+    
+    _searchArr = [[NSMutableArray alloc] init];
+    
+    _searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
+    _searchController.hidesNavigationBarDuringPresentation = NO;
+    _searchController.searchBar.tintColor = UIColor.whiteColor;
+    _searchController.dimsBackgroundDuringPresentation = NO;
+    _searchController.searchBar.delegate = self;
+    [self.tableView setTableHeaderView:_searchController.searchBar];
 }
 
 - (void)didReceiveMemoryWarning {
@@ -44,30 +105,90 @@
     [self.tableView reloadData];
 }
 
-- (void)setDataArr:(NSMutableArray *)dataArr{
-    _dataArr = dataArr;
+- (void)viewWillDisappear:(BOOL)animated
+{
+    [super viewWillDisappear:animated];
+    [self.searchController setActive:NO];
+}
+
+
+- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
+{
+    NSLog(@"textDidChange %@  %@", searchBar.text, searchText);
+    
+    if(searchText.length > 0)
+    {
+        [self.searchArr removeAllObjects];
+        
+        for(int i=0; i<_dataArr.count; i++)
+        {
+            FriendRequestData *data = [_dataArr objectAtIndex:i];
+            NSString *name = [[User sharedInfo] getUserNameById:data.userId];
+            if([[name lowercaseString] containsString:[searchText lowercaseString]])
+            {
+                [_searchArr addObject:data];
+            }
+        }
+        
+        for(int i=0; i<_systemArr.count; i++)
+        {
+            NIMSystemNotification *notification = [_systemArr objectAtIndex:i];
+            NSString *name = [[User sharedInfo] getUserNameById:notification.sourceID];
+            if([[name lowercaseString] containsString:[searchText lowercaseString]])
+            {
+                [_searchArr addObject:notification];
+            }
+        }
+    }
+    else
+    {
+        [self.searchArr removeAllObjects];
+    }
+    
+    [self.tableView reloadData];
+}
+
+- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
+{
+    [self.searchArr removeAllObjects];
+    [self.tableView reloadData];
 }
 
 
-#pragma mark - Table view data source
 
-- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
-    return 1;
+
+- (void)setDataArr:(NSMutableArray *)dataArr{
+    _dataArr = dataArr;
 }
 
+
+#pragma mark - Table view data source
 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
-    if(!_dataArr)
-        return 0;
-    return _dataArr.count;
+    if(_searchArr.count)
+        return _searchArr.count;
+    return _dataArr.count + _systemArr.count;
 }
 
 
 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
     FriendRequestTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Request"];
-    
     cell.delegate = self;
-    [cell setData:[_dataArr objectAtIndex:indexPath.row]];
     
+    if(_searchArr.count)
+    {
+        [cell setData:[_searchArr objectAtIndex:indexPath.row]];
+    }
+    else
+    {
+        if(indexPath.row < _dataArr.count)
+        {
+            [cell setData:[_dataArr objectAtIndex:indexPath.row]];
+        }
+        else
+        {
+            [cell setData:[_systemArr objectAtIndex:indexPath.row-_dataArr.count]];
+        }
+    }
     return cell;
 }
 
@@ -75,37 +196,67 @@
 
 
 
-- (void)friendRequestAccept:(FriendRequestData *)data{
-    __weak typeof(self) wself = self;
+- (void)friendRequestAccept:(id)data{
     
-    [[HttpRequest shared] addFriend:data.requestId targetId:data.userId success:^{
-        [wself.view makeToast:@"添加成功" duration:2.0 position:CSToastPositionCenter];
-        [wself removeData:data.requestId];
-    } failure:^{
-        [wself.view makeToast:@"添加失败" duration:2.0 position:CSToastPositionCenter];
-    }];
+    if([data isKindOfClass:[NIMSystemNotification class]])
+    {
+        [self onAccept:(NIMSystemNotification *)data];
+    }
+    else
+    {
+        FriendRequestData *friendRequestData = (FriendRequestData *)data;
+        __weak typeof(self) wself = self;
+        [[HttpRequest shared] addFriend:friendRequestData.requestId targetId:friendRequestData.userId success:^{
+            [wself.view makeToast:@"添加成功" duration:2.0 position:CSToastPositionCenter];
+            [wself removeData:friendRequestData.requestId];
+        } failure:^{
+            [wself.view makeToast:@"添加失败" duration:2.0 position:CSToastPositionCenter];
+        }];
+    }
 }
 
 
-- (void)friendRequestDelete:(NSString *)requestId{
-    UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:nil delegate:nil cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"删除", nil];
+- (void)friendRequestDelete:(id)data{
     
-    __weak typeof(self) wself = self;
-    [sheet showInView:self.view completionHandler:^(NSInteger index) {
-        switch (index) {
-            case 0:
-            {
-                [[HttpRequest shared] deleteFriendRequest:requestId success:^{
-                    [wself removeData:requestId];
-                } failure:^{
-                    [wself.view makeToast:@"删除失败" duration:2.0 position:CSToastPositionCenter];
-                }];
-                break;
+    if([data isKindOfClass:[NIMSystemNotification class]])
+    {
+        UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:nil delegate:nil cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"删除", nil];
+        
+        __weak typeof(self) wself = self;
+        [sheet showInView:self.view completionHandler:^(NSInteger index) {
+            switch (index) {
+                case 0:
+                {
+                    [wself onRefuse:(NIMSystemNotification *)data];
+                    break;
+                }
+                default:
+                    break;
             }
-            default:
-                break;
-        }
-    }];
+        }];
+        
+    }
+    else
+    {
+        UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:nil delegate:nil cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"删除", nil];
+        FriendRequestData *friendRequestData = data;
+        __weak typeof(self) wself = self;
+        [sheet showInView:self.view completionHandler:^(NSInteger index) {
+            switch (index) {
+                case 0:
+                {
+                    [[HttpRequest shared] deleteFriendRequest:friendRequestData.requestId success:^{
+                        [wself removeData:friendRequestData.requestId];
+                    } failure:^{
+                        [wself.view makeToast:@"删除失败" duration:2.0 position:CSToastPositionCenter];
+                    }];
+                    break;
+                }
+                default:
+                    break;
+            }
+        }];
+    }
 }
 
 - (void)removeData:(NSString *)requestId
@@ -123,4 +274,198 @@
     [self.tableView reloadData];
 }
 
+
+
+
+- (void)onAccept:(NIMSystemNotification *)notification
+{
+    __weak typeof(self) wself = self;
+    switch (notification.type) {
+        case NIMSystemNotificationTypeTeamApply:{
+            [[NIMSDK sharedSDK].teamManager passApplyToTeam:notification.targetID userId:notification.sourceID completion:^(NSError *error, NIMTeamApplyStatus applyStatus) {
+                if (!error) {
+                    [wself.navigationController.view makeToast:@"同意成功"
+                                                      duration:2
+                                                      position:CSToastPositionCenter];
+                    notification.handleStatus = NotificationHandleTypeOk;
+                    [wself deleteNotification:notification];
+                    [wself.tableView reloadData];
+                }else {
+                    if(error.code == NIMRemoteErrorCodeTimeoutError) {
+                        [wself.navigationController.view makeToast:@"网络问题,请重试"
+                                                          duration:2
+                                                          position:CSToastPositionCenter];
+                    } else {
+                        notification.handleStatus = NotificationHandleTypeOutOfDate;
+                    }
+                    [wself.tableView reloadData];
+                    DDLogDebug(@"%@",error.localizedDescription);
+                }
+            }];
+            break;
+        }
+        case NIMSystemNotificationTypeTeamInvite:{
+            [[NIMSDK sharedSDK].teamManager acceptInviteWithTeam:notification.targetID invitorId:notification.sourceID completion:^(NSError *error) {
+                if (!error) {
+                    [wself.navigationController.view makeToast:@"接受成功"
+                                                      duration:2
+                                                      position:CSToastPositionCenter];
+                    notification.handleStatus = NotificationHandleTypeOk;
+                    [wself deleteNotification:notification];
+                    [wself.tableView reloadData];
+                }else {
+                    if(error.code == NIMRemoteErrorCodeTimeoutError) {
+                        [wself.navigationController.view makeToast:@"网络问题,请重试"
+                                                          duration:2
+                                                          position:CSToastPositionCenter];
+                    }
+                    else if (error.code == NIMRemoteErrorCodeTeamNotExists) {
+                        [wself.navigationController.view makeToast:@"群不存在"
+                                                          duration:2
+                                                          position:CSToastPositionCenter];
+                    }
+                    else {
+                        notification.handleStatus = NotificationHandleTypeOutOfDate;
+                    }
+                    [wself.tableView reloadData];
+                    DDLogDebug(@"%@",error.localizedDescription);
+                }
+            }];
+        }
+            break;
+        case NIMSystemNotificationTypeFriendAdd:
+        {
+            NIMUserRequest *request = [[NIMUserRequest alloc] init];
+            request.userId = notification.sourceID;
+            request.operation = NIMUserOperationVerify;
+            
+            [[[NIMSDK sharedSDK] userManager] requestFriend:request
+                                                 completion:^(NSError *error) {
+                                                     if (!error) {
+                                                         [wself.navigationController.view makeToast:@"验证成功"
+                                                                                           duration:2
+                                                                                           position:CSToastPositionCenter];
+                                                         notification.handleStatus = NotificationHandleTypeOk;
+                                                     }
+                                                     else
+                                                     {
+                                                         [wself.navigationController.view makeToast:@"验证失败,请重试"
+                                                                                           duration:2
+                                                                                           position:CSToastPositionCenter];
+                                                     }
+                                                     [wself.tableView reloadData];
+                                                     DDLogDebug(@"%@",error.localizedDescription);
+                                                 }];
+        }
+            break;
+        default:
+            break;
+    }
+}
+
+- (void)onRefuse:(NIMSystemNotification *)notification
+{
+    __weak typeof(self) wself = self;
+    switch (notification.type) {
+        case NIMSystemNotificationTypeTeamApply:{
+            [[NIMSDK sharedSDK].teamManager rejectApplyToTeam:notification.targetID userId:notification.sourceID rejectReason:@"" completion:^(NSError *error) {
+                if (!error) {
+                    [wself.navigationController.view makeToast:@"拒绝成功"
+                                                      duration:2
+                                                      position:CSToastPositionCenter];
+                    notification.handleStatus = NotificationHandleTypeNo;
+                    [wself deleteNotification:notification];
+                    [wself.tableView reloadData];
+                }else {
+                    if(error.code == NIMRemoteErrorCodeTimeoutError) {
+                        [wself.navigationController.view makeToast:@"网络问题,请重试"
+                                                          duration:2
+                                                          position:CSToastPositionCenter];
+                    } else {
+                        notification.handleStatus = NotificationHandleTypeOutOfDate;
+                        [wself deleteNotification:notification];
+                    }
+                    [wself.tableView reloadData];
+                    DDLogDebug(@"%@",error.localizedDescription);
+                }
+            }];
+        }
+            break;
+            
+        case NIMSystemNotificationTypeTeamInvite:{
+            [[NIMSDK sharedSDK].teamManager rejectInviteWithTeam:notification.targetID invitorId:notification.sourceID rejectReason:@"" completion:^(NSError *error) {
+                if (!error) {
+                    [wself.navigationController.view makeToast:@"拒绝成功"
+                                                      duration:2
+                                                      position:CSToastPositionCenter];
+                    notification.handleStatus = NotificationHandleTypeNo;
+                    [wself deleteNotification:notification];
+                    [wself.tableView reloadData];
+                }else {
+                    if(error.code == NIMRemoteErrorCodeTimeoutError) {
+                        [wself.navigationController.view makeToast:@"网络问题,请重试"
+                                                          duration:2
+                                                          position:CSToastPositionCenter];
+                    }
+                    else if (error.code == NIMRemoteErrorCodeTeamNotExists) {
+                        [wself.navigationController.view makeToast:@"群不存在"
+                                                          duration:2
+                                                          position:CSToastPositionCenter];
+                    }
+                    else {
+                        notification.handleStatus = NotificationHandleTypeOutOfDate;
+                    }
+                    [wself.tableView reloadData];
+                    DDLogDebug(@"%@",error.localizedDescription);
+                }
+            }];
+            
+        }
+            break;
+        case NIMSystemNotificationTypeFriendAdd:
+        {
+            NIMUserRequest *request = [[NIMUserRequest alloc] init];
+            request.userId = notification.sourceID;
+            request.operation = NIMUserOperationReject;
+            
+            [[[NIMSDK sharedSDK] userManager] requestFriend:request
+                                                 completion:^(NSError *error) {
+                                                     if (!error) {
+                                                         [wself.navigationController.view makeToast:@"拒绝成功"
+                                                                                           duration:2
+                                                                                           position:CSToastPositionCenter];
+                                                         notification.handleStatus = NotificationHandleTypeNo;
+                                                     }
+                                                     else
+                                                     {
+                                                         [wself.navigationController.view makeToast:@"拒绝失败,请重试"
+                                                                                           duration:2
+                                                                                           position:CSToastPositionCenter];
+                                                     }
+                                                     [wself.tableView reloadData];
+                                                     DDLogDebug(@"%@",error.localizedDescription);
+                                                 }];
+        }
+            break;
+        case NIMSystemNotificationTypeTeamApplyReject:
+        case NIMSystemNotificationTypeTeamIviteReject:
+        {
+            [wself deleteNotification:notification];
+            [wself.tableView reloadData];
+        }
+            break;
+        default:
+            break;
+    }
+}
+
+
+- (void)deleteNotification:(NIMSystemNotification *)notification
+{
+    id<NIMSystemNotificationManager> systemNotificationManager = [[NIMSDK sharedSDK] systemNotificationManager];
+    [systemNotificationManager deleteNotification:notification];
+    
+    [_systemArr removeObject:notification];
+}
+
 @end

+ 152 - 11
NIMDemo/NIMDemo/FriendViewController.m

@@ -23,11 +23,16 @@
 #import "NTESContactViewController.h"
 #import "NTESContactAddFriendViewController.h"
 #import "User.h"
-#import "ContactViewController.h"
+#import "FriendListViewController.h"
+#import "NIMSessionListCell.h"
+#import "NIMAvatarImageView.h"
+#import "NTESShareAttachment.h"
+#import "HttpRequest.h"
+#import "NTESBadgeView.h"
 
 #define SessionListTitle @"谁说"
 
-@interface FriendViewController ()<NIMLoginManagerDelegate,NTESListHeaderDelegate,NIMEventSubscribeManagerDelegate,UIViewControllerPreviewingDelegate>
+@interface FriendViewController ()<NIMLoginManagerDelegate,NTESListHeaderDelegate,NIMEventSubscribeManagerDelegate,UIViewControllerPreviewingDelegate,UISearchBarDelegate>
 
 @property (nonatomic,strong) UILabel *titleLabel;
 
@@ -37,6 +42,14 @@
 
 @property (nonatomic,strong) NSMutableDictionary *previews;
 
+@property (nonatomic, strong) NSMutableArray            *searchArr;
+@property (nonatomic, strong) UISearchController        *searchController;
+
+@property (nonatomic, strong) UIButton                  *contactBtn;
+@property (nonatomic, strong) NTESBadgeView             *badgeView;
+
+@property (nonatomic, strong) NSMutableArray            *requestArr;
+
 @end
 
 @implementation FriendViewController
@@ -84,6 +97,17 @@
         [wself sort];
         [wself refresh:YES];
     }];
+    
+    _searchArr = [[NSMutableArray alloc] init];
+    
+    _searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
+    //_searchController.searchBar.barTintColor = User.orangeColor;
+    _searchController.hidesNavigationBarDuringPresentation = NO;
+    _searchController.searchBar.tintColor = UIColor.whiteColor;
+    //_searchController.delegate = self;
+    _searchController.dimsBackgroundDuringPresentation = NO;
+    _searchController.searchBar.delegate = self;
+    [self.tableView setTableHeaderView:_searchController.searchBar];
 }
 
 - (void)viewWillAppear:(BOOL)animated{
@@ -100,11 +124,20 @@
     
     [navItem setLeftBarButtonItems:@[leftItem]];
     
-    UIButton *contactBtn = [UIButton buttonWithType:UIButtonTypeCustom];
-    [contactBtn setImage:[UIImage imageNamed:@"朋友_03"] forState:UIControlStateNormal];
-    [contactBtn addTarget:self action:@selector(showContact:) forControlEvents:UIControlEventTouchUpInside];
-    [contactBtn sizeToFit];
-    UIBarButtonItem *contactItem = [[UIBarButtonItem alloc] initWithCustomView:contactBtn];
+    _contactBtn = [UIButton buttonWithType:UIButtonTypeCustom];
+    [_contactBtn setImage:[UIImage imageNamed:@"朋友_03"] forState:UIControlStateNormal];
+    [_contactBtn addTarget:self action:@selector(showContact:) forControlEvents:UIControlEventTouchUpInside];
+    [_contactBtn sizeToFit];
+    UIBarButtonItem *contactItem = [[UIBarButtonItem alloc] initWithCustomView:_contactBtn];
+    
+    _badgeView = [NTESBadgeView viewWithBadgeTip:@""];
+    _badgeView.right = 20;
+    _badgeView.top = -10;
+    [_contactBtn addSubview:_badgeView];
+    
+    UIButton *spaceBtn = [UIButton buttonWithType:UIButtonTypeCustom];
+    spaceBtn.frame = CGRectMake(0, 2, 10, 10);
+    UIBarButtonItem *spaceItem = [[UIBarButtonItem alloc] initWithCustomView:spaceBtn];
     
     UIButton *addBtn = [UIButton buttonWithType:UIButtonTypeCustom];
     [addBtn setImage:[UIImage imageNamed:@"创建群_07"] forState:UIControlStateNormal];
@@ -112,10 +145,59 @@
     [addBtn sizeToFit];
     UIBarButtonItem *addItem = [[UIBarButtonItem alloc] initWithCustomView:addBtn];
     
-    [navItem setRightBarButtonItems:@[addItem, contactItem]];
+    [navItem setRightBarButtonItems:@[addItem, spaceItem, contactItem]];
+    
+    [[User sharedInfo] removeNotJoinTeamConversation];
+    [super resetRecentSessions];
+    
+    __weak typeof(self) wself = self;
+    [[HttpRequest shared] requestFriendList:^(NSMutableArray<FriendRequestData *> * _Nullable dataArr) {
+        wself.requestArr = dataArr;
+        NSInteger systemCount = [[[NIMSDK sharedSDK] systemNotificationManager] allUnreadCount];
+        NSInteger badge = dataArr.count + systemCount;
+        wself.badgeView.hidden = badge == 0;
+        wself.badgeView.badgeValue = [NSString stringWithFormat:@"%ld", (long)badge];
+    } failure:^{
+    }];
+}
+
+- (void)viewWillDisappear:(BOOL)animated
+{
+    [super viewWillDisappear:animated];
+    [self.searchController setActive:NO];
+}
+
+
+
+- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
+{
+    NSLog(@"textDidChange %@  %@", searchBar.text, searchText);
+    
+    if(searchText.length > 0)
+    {
+        [self.searchArr removeAllObjects];
+        for(int i=0; i<self.recentSessions.count; i++)
+        {
+            NIMRecentSession *recent = [self.recentSessions objectAtIndex:i];
+            NSString *name = [[self nameForRecentSession:recent] lowercaseString];
+            if([name containsString:[searchText lowercaseString]])
+            {
+                [_searchArr addObject:recent];
+            }
+        }
+    }
+    else
+    {
+        [self.searchArr removeAllObjects];
+    }
     
-    [self sort];
-    [self refresh:YES];
+    [self.tableView reloadData];
+}
+
+- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
+{
+    [self.searchArr removeAllObjects];
+    [self.tableView reloadData];
 }
 
 - (void)refresh:(BOOL)reload{
@@ -272,7 +354,51 @@
     [self.tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
 }
 
+#pragma mark - UITableViewDataSource
 
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
+    if(_searchArr.count)
+        return _searchArr.count;
+    return self.recentSessions.count;
+}
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
+    NIMRecentSession *recent = nil;
+    if(_searchArr.count)
+    {
+        recent = [_searchArr objectAtIndex:indexPath.row];
+    }
+    else
+    {
+        recent = self.recentSessions[indexPath.row];
+    }
+    
+    static NSString * cellId = @"cellId";
+    NIMSessionListCell * cell = [tableView dequeueReusableCellWithIdentifier:cellId];
+    if (!cell) {
+        cell = [[NIMSessionListCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
+        [cell.avatarImageView addTarget:self action:@selector(onTouchAvatar:) forControlEvents:UIControlEventTouchUpInside];
+    }
+    cell.nameLabel.text = [self nameForRecentSession:recent];
+    if(recent.session.sessionType == NIMSessionTypeP2P)
+    {
+        [cell.avatarImageView setAvatarBySession:recent.session];
+    }
+    else if(recent.session.sessionType == NIMSessionTypeTeam)
+    {
+        NIMTeam *team = [[NIMSDK sharedSDK].teamManager teamById:recent.session.sessionId];
+        NSURL *url = team.thumbAvatarUrl ? [NSURL URLWithString:team.thumbAvatarUrl] : nil;
+        [cell.avatarImageView nim_setImageWithURL:url placeholderImage:[User defaultTeamAvatar:team]];
+    }
+    [cell.nameLabel sizeToFit];
+    cell.messageLabel.attributedText  = [self contentForRecentSession:recent];
+    [cell.messageLabel sizeToFit];
+    cell.timeLabel.text = [self timestampDescriptionForRecentSession:recent];
+    [cell.timeLabel sizeToFit];
+    
+    [cell refresh:recent];
+    return cell;
+}
 
 #pragma mark - Private
 
@@ -330,6 +456,9 @@
         else if ([object.attachment isKindOfClass:[NTESGiftAttachment class]]) {
             text = @"[礼物]";
         }
+        else if ([object.attachment isKindOfClass:[NTESShareAttachment class]]) {
+            text = @"[分享]";
+        }
         else{
             text = @"[未知消息]";
         }
@@ -376,7 +505,8 @@
 - (void)showContact:(int)sender
 {
     UIStoryboard *board = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
-    ContactViewController *vc = [board instantiateViewControllerWithIdentifier:@"FriendList"];
+    FriendListViewController *vc = [board instantiateViewControllerWithIdentifier:@"FriendList"];
+    vc.requestArr = _requestArr;
     [self.navigationController pushViewController:vc animated:YES];
 }
 
@@ -406,4 +536,15 @@
         return NSOrderedSame;
     }];
 }
+
+- (void)onTouchAvatar:(id)sender{
+    UIView *view = [sender superview];
+    while (![view isKindOfClass:[UITableViewCell class]]) {
+        view = view.superview;
+    }
+    UITableViewCell *cell  = (UITableViewCell *)view;
+    NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
+    NIMRecentSession *recent = self.recentSessions[indexPath.row];
+    [self onSelectedAvatar:recent atIndexPath:indexPath];
+}
 @end

+ 1 - 0
NIMDemo/NIMDemo/GiftTopBarItem.h

@@ -14,5 +14,6 @@
 @property (nonatomic, strong) NSMutableDictionary *infoDict;
 
 -(void)setInfo:(NSMutableDictionary *)infoDict;
+-(void)setSystemInfo:(NSString *)info;
 
 @end

+ 52 - 12
NIMDemo/NIMDemo/GiftTopBarItem.m

@@ -17,6 +17,9 @@
 
 @interface GiftTopBarItem()
 
+@property (nonatomic, strong) UILabel                   *labelSystemInfo;
+
+@property (nonatomic, strong) UIView                    *container;
 @property (nonatomic, strong) NIMAvatarImageView       *avatarSender;
 @property (nonatomic, strong) UILabel                   *labelSender;
 @property (nonatomic, strong) NIMAvatarImageView       *avatarTarget;
@@ -34,47 +37,58 @@
     {
         self.backgroundColor = NIMKit_UIColorFromRGB(0xe4e7ec);
         
-        UIView *container = [[UIView alloc] initWithFrame:CGRectMake(20, 5, self.nim_right-40, 30)];
-        container.backgroundColor = UIColor.whiteColor;
-        container.layer.cornerRadius = 15;
-        [self addSubview:container];
+        UIView *bgView = [[UIView alloc] initWithFrame:CGRectMake(20, 5, self.nim_right-40, 30)];
+        bgView.backgroundColor = UIColor.whiteColor;
+        bgView.layer.cornerRadius = 15;
+        [self addSubview:bgView];
+        
+        _labelSystemInfo = [[UILabel alloc] initWithFrame:CGRectMake(30, 5, self.nim_right-60, 30)];
+        [_labelSystemInfo addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onSystemInfo:)]];
+        [_labelSystemInfo setUserInteractionEnabled:YES];
+        [self addSubview:_labelSystemInfo];
+        
+        _container = [[UIView alloc] initWithFrame:CGRectMake(20, 5, self.nim_right-40, 30)];
+        [self addSubview:_container];
         
         _avatarSender = [[NIMAvatarImageView alloc] initWithFrame:CGRectMake(10, 5, 20, 20)];
         [_avatarSender nim_setImageWithURL:nil placeholderImage:[UIImage imageNamed:@"avatar_user2"]];
-        [container addSubview:_avatarSender];
+        [_container addSubview:_avatarSender];
         
         _labelSender = [[UILabel alloc] initWithFrame:CGRectMake(_avatarSender.nim_right+2, 5, 65, 20)];
         _labelSender.textColor = User.greenColor;
         _labelSender.font = [UIFont systemFontOfSize:14];
-        [container addSubview:_labelSender];
+        [_container addSubview:_labelSender];
         
         UILabel *labelGive = [[UILabel alloc] initWithFrame:CGRectMake(_labelSender.nim_right+5, 5, 30, 20)];
         labelGive.text = @"送给";
         labelGive.font = [UIFont systemFontOfSize:14];
-        [container addSubview:labelGive];
+        [_container addSubview:labelGive];
         
         _avatarTarget = [[NIMAvatarImageView alloc] initWithFrame:CGRectMake(labelGive.nim_right+5, 5, 20, 20)];
         [_avatarTarget nim_setImageWithURL:nil placeholderImage:[UIImage imageNamed:@"avatar_user2"]];
-        [container addSubview:_avatarTarget];
+        [_container addSubview:_avatarTarget];
         
         _labelTarget = [[UILabel alloc] initWithFrame:CGRectMake(_avatarTarget.nim_right+2, 5, 70, 20)];
         _labelTarget.textColor = User.greenColor;
         _labelTarget.font = [UIFont systemFontOfSize:14];
-        [container addSubview:_labelTarget];
+        [_container addSubview:_labelTarget];
         
         _giftIcon = [[UIImageView alloc] initWithFrame:CGRectMake(_labelTarget.nim_right+10, 2, 26, 26)];
-        [container addSubview:_giftIcon];
+        [_container addSubview:_giftIcon];
         
         _labelCount = [[UILabel alloc] initWithFrame:CGRectMake(_giftIcon.nim_right+5, 5, 40, 20)];
         _labelCount.textColor = User.greenColor;
         _labelCount.font = [UIFont systemFontOfSize:14];
-        [container addSubview:_labelCount];
+        [_container addSubview:_labelCount];
     }
     return self;
 }
 
 - (void) setInfo:(NSMutableDictionary *)infoDict
 {
+    _labelSystemInfo.hidden = YES;
+    _container.hidden = NO;
+    
     _infoDict = infoDict;
     
     NSString *icon = [infoDict objectForKey:@"gift"];
@@ -115,7 +129,7 @@
             if(team)
             {
                 NSURL *url = team.avatarUrl ? [NSURL URLWithString:team.avatarUrl] : nil;
-                [_avatarTarget nim_setImageWithURL:url placeholderImage:[UIImage imageNamed:@"avatar_team"]];
+                [_avatarTarget nim_setImageWithURL:url placeholderImage:[User defaultTeamAvatar:team]];
                 
                 _labelTarget.text = team.teamName ? team.teamName : teamId;
             }
@@ -127,4 +141,30 @@
     _labelCount.text = [NSString stringWithFormat:@"x%@", count];
 }
 
+
+- (void)setSystemInfo:(NSString *)info
+{
+    _labelSystemInfo.hidden = NO;
+    _container.hidden = YES;
+    
+    NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] init];
+    NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys:
+                           [UIFont systemFontOfSize:15.0], NSFontAttributeName,
+                           User.orangeColor, NSForegroundColorAttributeName, nil];
+    NSMutableAttributedString *appendString = [[NSMutableAttributedString alloc] initWithString:@"[系统公告] " attributes:attrs];
+    [attrString appendAttributedString:appendString];
+    
+    attrs = [NSDictionary dictionaryWithObjectsAndKeys:
+             [UIFont systemFontOfSize:15.0], NSFontAttributeName, nil];
+    appendString = [[NSMutableAttributedString alloc] initWithString:info attributes:attrs];
+    [attrString appendAttributedString:appendString];
+    
+    _labelSystemInfo.attributedText = attrString;
+}
+
+- (void)onSystemInfo:(id)sender{
+    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:_labelSystemInfo.text message:nil delegate:nil cancelButtonTitle:@"确认" otherButtonTitles:nil];
+    [alertView show];
+}
+
 @end

+ 16 - 0
NIMDemo/NIMDemo/GroupAvatarTableViewCell.h

@@ -0,0 +1,16 @@
+//
+//  GroupAvatarTableViewCell.h
+//  NIM
+//
+//  Created by Fenix Wang on 2017/10/12.
+//  Copyright © 2017年 Netease. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface GroupAvatarTableViewCell : UITableViewCell
+
+- (void)initWidth:(CGFloat)width;
+- (void)setData:(NSDictionary *)data;
+
+@end

+ 53 - 0
NIMDemo/NIMDemo/GroupAvatarTableViewCell.m

@@ -0,0 +1,53 @@
+//
+//  GroupAvatarTableViewCell.m
+//  NIM
+//
+//  Created by Fenix Wang on 2017/10/12.
+//  Copyright © 2017年 Netease. All rights reserved.
+//
+
+#import "GroupAvatarTableViewCell.h"
+#import "NIMAvatarImageView.h"
+#import "User.h"
+
+@interface GroupAvatarTableViewCell()
+
+@property (nonatomic, strong) UILabel               *titleLabel;
+@property (nonatomic, strong) NIMAvatarImageView    *avatar;
+
+@end
+
+@implementation GroupAvatarTableViewCell
+
+- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
+    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
+    if(self)
+    {
+        [self setSelectionStyle:UITableViewCellSelectionStyleNone];
+    }
+    return self;
+}
+
+- (void)initWidth:(CGFloat)width{
+    
+    _titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, (66 - 30)/2, 120, 30)];
+    _titleLabel.textColor = UIColor.blackColor;
+    [self addSubview:_titleLabel];
+    
+    _avatar = [[NIMAvatarImageView alloc] initWithFrame:CGRectMake(width - 44 - 10, (66-44)/2, 44, 44)];
+    [_avatar setUserInteractionEnabled:NO];
+    [_avatar setEnabled:NO];
+    [self addSubview:_avatar];
+    
+}
+
+- (void)setData:(NSDictionary *)data{
+    
+    _titleLabel.text = [data objectForKey:@"title"];
+    NIMTeam *team = [data objectForKey:@"value"];
+    NSURL *url = team.avatarUrl && team.avatarUrl.length ? [NSURL URLWithString:team.avatarUrl] : nil;
+    [_avatar nim_setImageWithURL:url placeholderImage:[User defaultTeamAvatar:team]];
+    
+}
+
+@end

+ 157 - 8
NIMDemo/NIMDemo/GroupInfoViewController.m

@@ -21,15 +21,20 @@
 #import "NIMKit.h"
 #import "UIActionSheet+NTESBlock.h"
 #import "NTESBundleSetting.h"
+#import "UIImage+NIM.h"
+#import "SVProgressHUD.h"
+#import "GroupAvatarTableViewCell.h"
 
 
-@interface GroupInfoViewController () <UIAlertViewDelegate>
+@interface GroupInfoViewController () <UIAlertViewDelegate, UIImagePickerControllerDelegate,
+UINavigationControllerDelegate>
 
 @property (nonatomic, strong) UITableView           *tableView;
 @property (nonatomic, strong) NIMSession            *session;
 @property (nonatomic, strong) NIMTeam               *team;
 @property (nonatomic, strong) NSMutableArray        *sectionArr;
 
+@property (nonatomic, strong) NSMutableDictionary   *teamAvatarData;
 @property (nonatomic, strong) NSMutableDictionary   *teamNameData;
 @property (nonatomic, strong) NSMutableDictionary   *teamIntroData;
 @property (nonatomic, strong) NSMutableDictionary   *teamMemberCountData;
@@ -69,6 +74,13 @@
     
     [self.view addSubview:self.tableView];
     [self buildBodyData];
+    
+    if([[User sharedInfo] isTeamOwner:_team])
+    {
+        [[User sharedInfo] requestFollowList:^{
+            
+        }];
+    }
 }
 
 - (void)didReceiveMemoryWarning {
@@ -119,6 +131,15 @@
     BOOL isSystemTeam = [[User sharedInfo] isSystemTeam:_session.sessionId];
     
     NSMutableArray *infoArr = [[NSMutableArray alloc] init];
+    
+    _teamAvatarData = [[NSMutableDictionary alloc] init];
+    [_teamAvatarData setValue:@"avatar" forKey:@"key"];
+    [_teamAvatarData setValue:_team forKey:@"value"];
+    NSString *teamAvatar = isSystemTeam ? @"聊天室头像" : @"群聊头像";
+    [_teamAvatarData setValue:teamAvatar forKey:@"title"];
+    [_teamAvatarData setValue:@(66) forKey:@"height"];
+    [infoArr addObject:_teamAvatarData];
+    
     _teamNameData = [[NSMutableDictionary alloc] init];
     [_teamNameData setValue:@"name" forKey:@"key"];
     [_teamNameData setValue:_team.teamName ? _team.teamName : @"" forKey:@"value"];
@@ -153,6 +174,7 @@
     [_teamNameData setValue:@"member" forKey:@"key"];
     [_teamNameData setValue:@"群聊成员" forKey:@"title"];
     [_teamNameData setValue:@(88) forKey:@"height"];
+    [_teamNameData setValue:_team forKey:@"team"];
     
     __weak typeof(self) wself = self;
     [self requestData:^(NSError *error) {
@@ -275,8 +297,19 @@
     
     UITableViewCell *baseCell = nil;
     
-    
-    if([key isEqualToString:@"name"] || [key isEqualToString:@"clear"])
+    if([key isEqualToString:@"avatar"])
+    {
+        GroupAvatarTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"avatar"];
+        if(!cell)
+        {
+            cell = [[GroupAvatarTableViewCell alloc] init];
+            [cell initWidth:self.view.width];
+            [cell setData:dataObj];
+            [cell setRestorationIdentifier:@"avatar"];
+        }
+        baseCell = cell;
+    }
+    else if([key isEqualToString:@"name"] || [key isEqualToString:@"clear"])
     {
         GroupNameTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"name"];
         if(!cell)
@@ -284,6 +317,7 @@
             cell = [[GroupNameTableViewCell alloc] init];
             [cell initWidth:self.view.width];
             [cell setData:dataObj];
+            [cell setRestorationIdentifier:@"name"];
         }
         baseCell = cell;
     }
@@ -295,6 +329,7 @@
             cell = [[GroupDescTableViewCell alloc] init];
             [cell initSize:self.view.width height:height];
             [cell setData:dataObj];
+            [cell setRestorationIdentifier:@"intro"];
         }
         baseCell = cell;
     }
@@ -306,6 +341,7 @@
             cell = [[GroupMenberCountTableViewCell alloc] init];
             [cell initSize:self.view.width height:height];
             [cell setData:dataObj];
+            [cell setRestorationIdentifier:@"count"];
         }
         baseCell = cell;
     }
@@ -317,6 +353,7 @@
             cell = [[GroupMenberTableViewCell alloc] init];
             [cell initSize:self.view.width height:height];
             [cell setData:dataObj];
+            [cell setRestorationIdentifier:@"member"];
         }
         baseCell = cell;
     }
@@ -328,6 +365,7 @@
             cell = [[GroupToogleTableViewCell alloc] init];
             [cell initSize:self.view.width height:height];
             [cell setData:dataObj];
+            [cell setRestorationIdentifier:@"disturb"];
         }
         baseCell = cell;
     }
@@ -361,7 +399,11 @@
     NSDictionary *dataObj = [arr objectAtIndex:indexPath.row];
     NSString *key = [dataObj objectForKey:@"key"];
     
-    if([key isEqualToString:@"name"])
+    if([key isEqualToString:@"avatar"])
+    {
+        [self updateTeamAvatar];
+    }
+    else if([key isEqualToString:@"name"])
     {
         [self updateTeamName];
     }
@@ -383,19 +425,100 @@
     }
 }
 
-
+- (void)updateTeamAvatar{
+    if([_team.owner isEqualToString:[NIMSDK sharedSDK].loginManager.currentAccount])
+    {
+        [self showImagePicker:UIImagePickerControllerSourceTypePhotoLibrary];
+    }
+}
 
 - (void)updateTeamName{
     
     if([[User sharedInfo] isTeamOwner:_team])
     {
-        _updateTeamNameAlertView = [[UIAlertView alloc] initWithTitle:@"" message:@"修改群名称" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确认", nil];
-        _updateTeamNameAlertView.alertViewStyle = UIAlertViewStylePlainTextInput;
-        [_updateTeamNameAlertView show];
+        if([[User sharedInfo] isSystemTeam:_team.teamId])
+        {
+            //[self showImagePicker:UIImagePickerControllerSourceTypePhotoLibrary];
+        }
+        else
+        {
+            _updateTeamNameAlertView = [[UIAlertView alloc] initWithTitle:@"" message:@"修改群名称" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确认", nil];
+            _updateTeamNameAlertView.alertViewStyle = UIAlertViewStylePlainTextInput;
+            [_updateTeamNameAlertView show];
+        }
     }
     
 }
 
+
+- (void)showImagePicker:(UIImagePickerControllerSourceType)type{
+    UIImagePickerController *picker = [[UIImagePickerController alloc] init];
+    picker.delegate      = self;
+    picker.sourceType    = type;
+    picker.allowsEditing = YES;
+    [self presentViewController:picker animated:YES completion:nil];
+}
+
+
+#pragma mark - UIImagePickerControllerDelegate
+- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
+    UIImage *image = info[UIImagePickerControllerEditedImage];
+    [picker dismissViewControllerAnimated:YES completion:^{
+        [self uploadImage:image];
+    }];
+}
+
+- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
+    [picker dismissViewControllerAnimated:YES completion:nil];
+}
+
+
+#pragma mark - Private
+- (void)uploadImage:(UIImage *)image{
+    UIImage *imageForAvatarUpload = [image nim_imageForAvatarUpload];
+    NSString *fileName = [[[[NSUUID UUID] UUIDString] lowercaseString] stringByAppendingPathExtension:@"jpg"];
+    NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:fileName];
+    NSData *data = UIImageJPEGRepresentation(imageForAvatarUpload, 1.0);
+    BOOL success = data && [data writeToFile:filePath atomically:YES];
+    __weak typeof(self) wself = self;
+    if (success) {
+        [SVProgressHUD show];
+        [[NIMSDK sharedSDK].resourceManager upload:filePath progress:nil completion:^(NSString *urlString, NSError *error) {
+            [SVProgressHUD dismiss];
+            if (!error && wself) {
+                if(urlString.length > 0)
+                {
+                    [[NIMSDK sharedSDK].teamManager updateTeamAvatar:urlString teamId:_team.teamId completion:^(NSError * _Nullable error) {
+                        if(error)
+                        {
+                            [wself.view makeToast:@"聊天室图标失败,请重试"
+                                         duration:2
+                                         position:CSToastPositionCenter];
+                        }
+                        else
+                        {
+                            [wself.view makeToast:@"图片上传成功"
+                                         duration:2
+                                         position:CSToastPositionCenter];
+                            [_team setAvatarUrl:urlString];
+                            [wself.tableView reloadData];
+                        }
+                    }];
+                }
+            }else{
+                [wself.view makeToast:@"图片上传失败,请重试"
+                             duration:2
+                             position:CSToastPositionCenter];
+            }
+        }];
+    }else{
+        [self.view makeToast:@"图片保存失败,请重试"
+                    duration:2
+                    position:CSToastPositionCenter];
+    }
+}
+
+
 - (void)updateTeamIntro{
     
     if([[User sharedInfo] isTeamOwner:_team])
@@ -404,6 +527,30 @@
         _updateTeamIntroAlertView.alertViewStyle = UIAlertViewStylePlainTextInput;
         [_updateTeamIntroAlertView show];
     }
+    else
+    {
+        if([[User sharedInfo] isSystemTeam:_team.teamId])
+        {
+            __weak typeof(self) wself = self;
+            [[User sharedInfo] fetchChatRoomIntro:^(NSString * _Nullable intro) {
+                [wself showTeamIntro:intro];
+            }];
+        }
+        else
+        {
+            [self showTeamIntro:_team.intro ? _team.intro : @""];
+        }
+        
+        
+    }
+}
+
+- (void)showTeamIntro:(NSString *)intro{
+    
+    NSString *title = [[User sharedInfo] isSystemTeam:_team.teamId] ? @"聊天室注意事项" : @"群公告";
+    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title message:intro delegate:self cancelButtonTitle:nil otherButtonTitles:@"确认", nil];
+    [alertView show];
+    
 }
 
 - (void)enterMemberCard{
@@ -521,6 +668,7 @@
         case 0://取消
             break;
         case 1:{
+            __weak typeof(self) wself = self;
             [[NIMSDK sharedSDK].teamManager quitTeam:self.team.teamId completion:^(NSError *error) {
                 if (!error) {
                     UIStoryboard *board = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
@@ -543,6 +691,7 @@
         case 0://取消
             break;
         case 1:{
+            __weak typeof(self) wself = self;
             [[NIMSDK sharedSDK].teamManager dismissTeam:self.team.teamId completion:^(NSError *error) {
                 if (!error) {
                     UIStoryboard *board = [UIStoryboard storyboardWithName:@"Main" bundle:nil];

+ 15 - 10
NIMDemo/NIMDemo/GroupMoreTableViewCell.m

@@ -9,6 +9,7 @@
 #import "GroupMoreTableViewCell.h"
 
 #import "NIMAvatarImageView.h"
+#import "User.h"
 
 @interface GroupMoreTableViewCell ()
 
@@ -35,17 +36,21 @@
 
 - (void)setData:(NSDictionary *)data{
     self.titleTextField.text = [data objectForKey:@"name"];
-    self.descTextField.text = [data objectForKey:@"desc"];
     
-    if(!_avatar)
-    {
-        _avatar = [[NIMAvatarImageView alloc] initWithFrame:[_avatarContainer bounds]];
-        [self.avatarContainer addSubview:_avatar];
-    }
-    
-    NSString *avatar = [data objectForKey:@"avatar"];
-    NSURL *avatarUrl = avatar.length ? [NSURL URLWithString:avatar] : nil;
-    [_avatar nim_setImageWithURL:avatarUrl placeholderImage:[UIImage imageNamed:@"avatar_team"]];
+    NSString *teamId = [data objectForKey:@"sid"];
+    __weak typeof(self) wself = self;
+    [[NIMSDK sharedSDK].teamManager fetchTeamInfo:teamId completion:^(NSError * _Nullable error, NIMTeam * _Nullable team) {
+        wself.descTextField.text = team.intro ? team.intro : @"";
+        if(!wself.avatar)
+        {
+            wself.avatar = [[NIMAvatarImageView alloc] initWithFrame:[wself.avatarContainer bounds]];
+            [wself.avatarContainer addSubview:wself.avatar];
+        }
+        
+        NSURL *avatarUrl = team.avatarUrl && team.avatarUrl.length ? [NSURL URLWithString:team.avatarUrl] : nil;
+        [wself.avatar nim_setImageWithURL:avatarUrl placeholderImage:[User defaultTeamAvatar:team]];
+    }];
+
     
     NSString *dist = [data objectForKey:@"dist"];
     if(dist)

+ 12 - 35
NIMDemo/NIMDemo/GroupMoreTableViewController.m

@@ -162,14 +162,14 @@
     
     self.navigationItem.title = @"附近群聊";
     
-    UIButton *createBtn = [UIButton buttonWithType:UIButtonTypeCustom];
-    [createBtn setTitle:@"创建" forState:UIControlStateNormal];
-    [createBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
-    [createBtn addTarget:self action:@selector(createGroup:) forControlEvents:UIControlEventTouchUpInside];
-    [createBtn sizeToFit];
-    
-    UIBarButtonItem *rightItem = [[UIBarButtonItem alloc] initWithCustomView:createBtn];
-    [self.navigationItem setRightBarButtonItem:rightItem];
+//    UIButton *createBtn = [UIButton buttonWithType:UIButtonTypeCustom];
+//    [createBtn setTitle:@"创建" forState:UIControlStateNormal];
+//    [createBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
+//    [createBtn addTarget:self action:@selector(createGroup:) forControlEvents:UIControlEventTouchUpInside];
+//    [createBtn sizeToFit];
+//    
+//    UIBarButtonItem *rightItem = [[UIBarButtonItem alloc] initWithCustomView:createBtn];
+//    [self.navigationItem setRightBarButtonItem:rightItem];
     
     
     User *user = [User sharedInfo];
@@ -201,19 +201,16 @@
         
         NSArray *list = [data objectForKey:@"list"];
         NSMutableArray *myTeams = [[NSMutableArray alloc] init];
+        
         for(int i=0; i<list.count; i++)
         {
             NSDictionary *obj = [list objectAtIndex:i];
             
             NSString *sid = [obj objectForKey:@"id"];
-            NIMTeam *team = [[NIMSDK sharedSDK].teamManager teamById:sid];
-            
             NSString *name = [obj objectForKey:@"name"] == nil ? @"" : [obj objectForKey:@"name"];
             NSString *dist = [obj objectForKey:@"dist"];
-            NSString *desc = team.intro == nil ? @"" : team.intro;
-            NSString *avatar = team.avatarUrl ? team.avatarUrl : @"";
             
-            NSDictionary *teamData = @{@"cid":@"Group", @"name":name, @"desc":desc, @"sid":sid, @"avatar":avatar, @"dist":dist};
+            NSDictionary *teamData = @{@"cid":@"Group", @"name":name, @"sid":sid, @"dist":dist};
             [myTeams addObject:teamData];
         }
         
@@ -266,29 +263,9 @@
     [self gotoTeamChat:sid];
 }
 
-- (void)gotoTeamChat:(NSString *)teamId{
-    
-    if([[NIMSDK sharedSDK].teamManager isMyTeam:teamId])
-    {
-        [self startTeamChat:teamId];
-    }
-    else
-    {
-        [[NIMSDK sharedSDK].teamManager applyToTeam:teamId message:@"" completion:^(NSError * _Nullable error, NIMTeamApplyStatus applyStatus) {
-            NSLog(@"applyToTeam error %@", error);
-            if(!error && applyStatus == NIMTeamApplyStatusAlreadyInTeam)
-            {
-                [self startTeamChat:teamId];
-            }
-        }];
-    }
-}
-
-- (void)startTeamChat:(NSString *)teamId
+- (void)gotoTeamChat:(NSString *)teamId
 {
-    NIMSession *session = [NIMSession session:teamId type:NIMSessionTypeTeam];
-    NTESSessionViewController *vc = [[NTESSessionViewController alloc] initWithSession:session];
-    [self.navigationController pushViewController:vc animated:YES];
+    [[User sharedInfo] attempJoinTeam:teamId vc:self];
 }
 
 /*

+ 106 - 20
NIMDemo/NIMDemo/GroupTableController.m

@@ -16,6 +16,9 @@
 #import <CoreLocation/CoreLocation.h>
 #import "AFNetworking/AFNetworking.h"
 #import "GroupMoreTableViewController.h"
+#import "UIAlertView+NTESBlock.h"
+#import "HttpRequest.h"
+#import "UIView+Toast.h"
 
 
 @interface GroupTableController () <CLLocationManagerDelegate>
@@ -51,11 +54,7 @@
     NSString *title = @"请重试定位";
     if(![user.district isEqualToString:@""])
     {
-        if([user.city isEqualToString:user.district])
-            title = user.city;
-        else
-            title = [NSString stringWithFormat:@"%@%@", user.city, user.district];
-        
+        title = user.district;
         if(title.length > 6)
         {
             title = [NSString stringWithFormat:@"%@%@", [title substringWithRange:NSMakeRange(0, 6)], @"..."];
@@ -89,10 +88,62 @@
     if(!self.groupArr)
         [self setDataList];
     
+    if([self checkNick])
+    {
+        [self checkAutoJoin];
+    }
+}
+
+- (bool)checkNick{
+    
+    NIMUser *nimUser = [[NIMSDK sharedSDK].userManager userInfo:[NIMSDK sharedSDK].loginManager.currentAccount];
+    if(nimUser.userInfo.nickName && nimUser.userInfo.nickName.length)
+    {
+        return true;
+    }
+    
+    __weak typeof(self) wself = self;
+    UIAlertView *nickAlert = [[UIAlertView alloc] initWithTitle:nil message:@"设置昵称" delegate:self cancelButtonTitle:nil otherButtonTitles:@"确认", nil];
+    nickAlert.alertViewStyle = UIAlertViewStylePlainTextInput;
+    [nickAlert showAlertWithCompletionHandler:^(NSInteger optIndex) {
+        NSString *nick = [nickAlert textFieldAtIndex:0].text;
+        if(nick.length > 0)
+        {
+            [SVProgressHUD show];
+            [[HttpRequest shared] updateNick:nick success:^{
+                [[NIMSDK sharedSDK].userManager updateMyUserInfo:@{@(NIMUserInfoUpdateTagNick) : nick} completion:^(NSError *error) {
+                    [SVProgressHUD dismiss];
+                    if (!error) {
+                        [wself.view makeToast:@"昵称设置成功"
+                                     duration:2
+                                     position:CSToastPositionBottom];
+                        [wself checkAutoJoin];
+                    }else{
+                        [wself.view makeToast:@"昵称设置失败,请重试"
+                                     duration:2
+                                     position:CSToastPositionBottom];
+                        [wself checkNick];
+                    }
+                }];
+            } failure:^{
+                [wself checkNick];
+            }];
+        }
+        else
+        {
+            [wself showNeedNickAlert];
+        }
+    }];
+    
+    return false;
+}
+
+- (void)checkAutoJoin{
+    User *user = [User sharedInfo];
     if(user.districtRoomId && user.districtRoomId.length > 0 && user.firstTimeJoin == YES)
     {
         user.firstTimeJoin = NO;
-        [self startTeamChat:user.districtRoomId animated:NO];
+        [self gotoTeamChat:user.districtRoomId animated:NO];
     }
     else
     {
@@ -100,6 +151,14 @@
     }
 }
 
+- (void)showNeedNickAlert{
+    __weak typeof(self) wself = self;
+    UIAlertView *nickAlert = [[UIAlertView alloc] initWithTitle:nil message:@"昵称不能为空" delegate:self cancelButtonTitle:@"确认" otherButtonTitles:nil, nil];
+    [nickAlert showAlertWithCompletionHandler:^(NSInteger optIndex) {
+        [wself checkNick];
+    }];
+}
+
 - (void) viewDidAppear:(BOOL)animated{
     [super viewDidAppear:animated];
     
@@ -107,7 +166,7 @@
     if([User sharedInfo].newCreateTeamId > 0)
     {
         [SVProgressHUD dismiss];
-        [self gotoTeamChat:[NSString stringWithFormat:@"%d", [User sharedInfo].newCreateTeamId]];
+        [self gotoTeamChat:[NSString stringWithFormat:@"%d", [User sharedInfo].newCreateTeamId] animated:YES];
         [User sharedInfo].newCreateTeamId = 0;
     }
     else
@@ -125,7 +184,7 @@
     
     NIMTeam *team = [[[NIMSDK sharedSDK] teamManager] teamById:user.countryRoomId];
     NSString *desc = [NSString stringWithFormat:@"%ld%@", (long)team.memberNumber, @"人热聊中"];
-    NSDictionary *county = @{@"cid":@"Group", @"name":@"国家聊天室", @"desc":desc, @"sid":user.countryRoomId, @"avatar":@""};
+    NSDictionary *county = @{@"cid":@"Group", @"name":@"国家频道", @"desc":desc, @"sid":user.countryRoomId, @"avatar":@""};
     [myTeams addObject:county];
     
     if(![user.provinceRoomId isEqualToString:@""] && user.provinceRoomId != nil)
@@ -168,9 +227,11 @@
         NSString *name = team.teamName == nil ? @"" : team.teamName;
         NSString *desc = [NSString stringWithFormat:@"%ld人热聊中", (long)team.memberNumber];
         NSString *sid = team.teamId;
-        NSString *avatar = team.avatarUrl ? team.avatarUrl : @"";
-        NSDictionary *teamData = @{@"cid":@"Group", @"name":name, @"desc":desc, @"sid":sid, @"avatar":avatar};
+        NSDictionary *teamData = @{@"cid":@"Group", @"name":name, @"desc":desc, @"sid":sid, @"team":team};
         [myTeams addObject:teamData];
+        
+        if(i >= 10)
+            break;
     }
     
     self.groupArr = myTeams;
@@ -233,7 +294,7 @@
             
         }
         else{
-            [self gotoTeamChat:sid];
+            [self gotoTeamChat:sid animated:YES];
         }
     }
     else if([cid isEqualToString:@"More"])
@@ -309,26 +370,51 @@
 
 - (IBAction)createGroup:(id)sender {
     
+    NSArray<NIMTeam *> *allMyTeams = [[NIMSDK sharedSDK].teamManager allMyTeams];
+    int countTeamJoined = 0;
+    for(int i=0; i<allMyTeams.count; i++)
+    {
+        NIMTeam *myTeam = [allMyTeams objectAtIndex:i];
+        if(![[User sharedInfo] isSystemTeam:myTeam.teamId])
+        {
+            countTeamJoined++;
+        }
+    }
+    
+    if(countTeamJoined >= 6)
+    {
+        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"最多只允许创建或加入6个群" message:nil delegate:nil cancelButtonTitle:@"确认" otherButtonTitles:nil];
+        [alertView show];
+        return;
+    }
+    
     [self performSegueWithIdentifier:@"createGroup" sender:self];
     
 }
 
 
-- (void)gotoTeamChat:(NSString *)teamId{
+- (void)gotoTeamChat:(NSString *)teamId animated:(BOOL)animated{
     
     if([[NIMSDK sharedSDK].teamManager isMyTeam:teamId])
     {
-        [self startTeamChat:teamId animated:YES];
+        [self startTeamChat:teamId animated:animated];
     }
     else
     {
-        [[NIMSDK sharedSDK].teamManager applyToTeam:teamId message:@"" completion:^(NSError * _Nullable error, NIMTeamApplyStatus applyStatus) {
-            NSLog(@"applyToTeam error %@", error);
-            if(!error && applyStatus == NIMTeamApplyStatusAlreadyInTeam)
-            {
-                [self startTeamChat:teamId animated:YES];
-            }
-        }];
+        if([[User sharedInfo] isSystemTeam:teamId])
+        {
+            [[NIMSDK sharedSDK].teamManager applyToTeam:teamId message:@"" completion:^(NSError * _Nullable error, NIMTeamApplyStatus applyStatus) {
+                NSLog(@"applyToTeam error %@", error);
+                if(!error && applyStatus == NIMTeamApplyStatusAlreadyInTeam)
+                {
+                    [self startTeamChat:teamId animated:animated];
+                }
+            }];
+        }
+        else
+        {
+            [[User sharedInfo] attempJoinTeam:teamId vc:self];
+        }
     }
 }
 

+ 7 - 3
NIMDemo/NIMDemo/GroupTableViewCell.m

@@ -8,6 +8,7 @@
 
 #import "GroupTableViewCell.h"
 #import "NIMAvatarImageView.h"
+#import "User.h"
 
 @interface GroupTableViewCell ()
 
@@ -41,8 +42,11 @@
         [self.avatarContainer addSubview:_avatar];
     }
     
-    NSString *avatar = [data objectForKey:@"avatar"];
-    NSURL *avatarUrl = avatar.length ? [NSURL URLWithString:avatar] : nil;
-    [_avatar nim_setImageWithURL:avatarUrl placeholderImage:[UIImage imageNamed:@"avatar_team"]];
+    NSString *sid = [data objectForKey:@"sid"];
+    [[NIMSDK sharedSDK].teamManager fetchTeamInfo:sid completion:^(NSError * _Nullable error, NIMTeam * _Nullable team) {
+        NSURL *avatarUrl = team.avatarUrl.length ? [NSURL URLWithString:team.avatarUrl] : nil;
+        [_avatar nim_setImageWithURL:avatarUrl placeholderImage:[User defaultTeamAvatar:team]];
+    }];
+    
 }
 @end

+ 56 - 0
NIMDemo/NIMDemo/HttpRequest/HttpRequest.h

@@ -15,6 +15,7 @@
 
 @interface HttpRequest : NSObject
 
+@property (nonatomic, strong) NSString * _Nullable urlRoot;
 
 @property (nonatomic, strong) NSString * _Nullable urlAbout;
 @property (nonatomic, strong) NSString * _Nullable urlLaw;
@@ -22,6 +23,7 @@
 
 
 
+
 + (instancetype _Nonnull )shared;
 
 
@@ -63,9 +65,14 @@
 
 //social
 - (void)getSocialDataList:(NSString *_Nullable)lastId
+                 targetId:(NSString *_Nullable)targetId
                   success:(void (^_Nullable)(NSMutableArray * _Nullable dataList))success
                   failure:(void (^_Nullable)())failure;
 
+- (void)deleteSocialData:(NSString *_Nullable)socialId
+                 success:(void (^_Nullable)(NSString * _Nullable socialId))success
+                 failure:(void (^_Nullable)())failure;
+
 - (void)socialLike:(NSString *_Nullable)socialId
            success:(void (^_Nullable)(NSString * _Nullable socialId, int currentLikes, NSMutableArray *_Nullable likeList))success
            failure:(void (^_Nullable)())failure;
@@ -92,7 +99,11 @@
 - (void)followList:(void (^_Nullable)(NSMutableArray * _Nullable follows))success
            failure:(void (^_Nullable)())failure;
 
+- (void)befollowedList:(void (^_Nullable)(NSMutableArray * _Nullable follows))success
+               failure:(void (^_Nullable)())failure;
+
 - (void)userInfo:(NSString *_Nullable)userId
+          search:(BOOL *_Nullable)search
        success:(void (^_Nullable)(UserInfo * _Nullable userInfo))success
        failure:(void (^_Nullable)())failure;
 
@@ -100,6 +111,15 @@
            success:(void (^_Nullable)())success
            failure:(void (^_Nullable)())failure;
 
+- (void)updateAlias:(NSString *_Nonnull)userId
+              alias:(NSString *_Nonnull)alias
+            success:(void (^_Nullable)())success
+            failure:(void (^_Nullable)())failure;
+
+- (void)fetchAlias:(NSMutableArray *_Nonnull)userIds
+           success:(void (^_Nullable)())success
+           failure:(void (^_Nullable)())failure;
+
 - (void)updateUserInfo:(NSMutableDictionary *_Nonnull)info
                success:(void (^_Nullable)())success
                failure:(void (^_Nullable)())failure;
@@ -116,6 +136,10 @@
             success:(void (^_Nullable)(NSMutableDictionary * _Nullable photoData))success
             failure:(void (^_Nullable)())failure;
 
+- (void)deletePhoto:(NSString *_Nullable)photoId
+            success:(void (^_Nullable)())success
+            failure:(void (^_Nullable)())failure;
+
 - (void)requestFriend:(NSString *_Nullable)userId
                   msg:(NSString *_Nullable)msg
               success:(void (^_Nullable)())success
@@ -145,6 +169,9 @@
              success:(void (^_Nullable)())success
              failure:(void (^_Nullable)())failure;
 
+- (void)tradePublishCount:(void (^_Nullable)(int count))success
+                  failure:(void (^_Nullable)())failure;
+
 - (void)tradeEdit:(NSString *_Nullable)tradeId
               msg:(NSString *_Nullable)msg
            picArr:(NSMutableArray *_Nullable)picArr
@@ -178,6 +205,10 @@
                   success:(void (^_Nullable)())success
                   failure:(void (^_Nullable)())failure;
 
+- (void)tradeInfo:(NSString *_Nullable)tradeId
+          success:(void (^_Nullable)(TradeData * _Nullable data))success
+          failure:(void (^_Nullable)())failure;
+
 
 //settings
 - (void)changeMobile:(NSString *_Nullable)mobile
@@ -186,6 +217,12 @@
              success:(void (^_Nullable)())success
              failure:(void (^_Nullable)())failure;
 
+- (void)forgetPassword:(NSString *_Nullable)mobile
+                  code:(NSString *_Nullable)code
+              password:(NSString *_Nullable)password
+               success:(void (^_Nullable)())success
+               failure:(void (^_Nullable)())failure;
+
 - (void)changePassword:(NSString *_Nullable)pwd
              changePwd:(NSString *_Nullable)changePwd
                success:(void (^_Nullable)())success
@@ -217,4 +254,23 @@
           success:(void (^_Nullable)(int inputTime))success
           failure:(void (^_Nullable)())failure;
 
+- (void)chatRoomIntro:(void (^_Nullable)(NSString * _Nullable intro))success
+              failure:(void (^_Nullable)())failure;
+
+- (void)lastSystemMsg:(void (^_Nullable)(NSMutableDictionary * _Nullable data))success
+              failure:(void (^_Nullable)())failure;
+
+- (void)resetLocation:(NSString *_Nullable)province
+                 city:(NSString *_Nullable)city
+             district:(NSString *_Nullable)district
+              success:(void (^_Nullable)())success
+              failure:(void (^_Nullable)())failure;
+
+
+//payment
+- (void)iosPayment:(NSString *_Nullable)code
+           receipt:(NSString *_Nullable)receipt
+           success:(void (^_Nullable)())success
+           failure:(void (^_Nullable)())failure;
+
 @end

+ 379 - 11
NIMDemo/NIMDemo/HttpRequest/HttpRequest.m

@@ -18,7 +18,7 @@
 
 @interface HttpRequest()
 
-@property (nonatomic, strong) NSString *urlRoot;
+
 
 //register & login
 @property (nonatomic, strong) NSString *urlLogin;
@@ -30,26 +30,36 @@
 
 //social
 @property (nonatomic, strong) NSString *urlSocialDataList;
+@property (nonatomic, strong) NSString *urlSocialDelete;
 @property (nonatomic, strong) NSString *urlSocialLike;
 @property (nonatomic, strong) NSString *urlSocialLikeList;
 @property (nonatomic, strong) NSString *urlSocialComment;
 @property (nonatomic, strong) NSString *urlSocialCommentList;
 @property (nonatomic, strong) NSString *urlFollow;
 @property (nonatomic, strong) NSString *urlFollowList;
+@property (nonatomic, strong) NSString *urlBefollowedList;
 @property (nonatomic, strong) NSString *urlUserInfo;
 @property (nonatomic, strong) NSString *urlUpdateUserInfo;
+@property (nonatomic, strong) NSString *urlUpdateAlias;
+@property (nonatomic, strong) NSString *urlFetchAlias;
 @property (nonatomic, strong) NSString *urlUpdateNick;
 @property (nonatomic, strong) NSString *urlUploadSocialBanner;
 @property (nonatomic, strong) NSString *urlNearUser;
 @property (nonatomic, strong) NSString *urlPhotoUpload;
+@property (nonatomic, strong) NSString *urlPhotoDelete;
 
 @property (nonatomic, strong) NSString *urlRequestFriend;
 @property (nonatomic, strong) NSString *urlFriendRequestList;
 @property (nonatomic, strong) NSString *urlAddFriend;
 @property (nonatomic, strong) NSString *urlDeleteFriendRequest;
 
+//chat
+@property (nonatomic, strong) NSString *urlChatRoomIntro;
+@property (nonatomic, strong) NSString *urlLastSystemMsg;
+
 //trade
 @property (nonatomic, strong) NSString *urlTradePublish;
+@property (nonatomic, strong) NSString *urlTradePublishCount;
 @property (nonatomic, strong) NSString *urlTradeEdit;
 @property (nonatomic, strong) NSString *urlTradeDelete;
 @property (nonatomic, strong) NSString *urlTradeDataList;
@@ -57,9 +67,11 @@
 @property (nonatomic, strong) NSString *urlTradeLatestDataList;
 @property (nonatomic, strong) NSString *urlTradeFollow;
 @property (nonatomic, strong) NSString *urlTradeDeleteFollow;
+@property (nonatomic, strong) NSString *urlTradeInfo;
 
 //setting
 @property (nonatomic, strong) NSString *urlChangeMobile;
+@property (nonatomic, strong) NSString *urlForgetPassword;
 @property (nonatomic, strong) NSString *urlChangePassword;
 @property (nonatomic, strong) NSString *urlFeedBack;
 @property (nonatomic, strong) NSString *urlHobbyList;
@@ -67,11 +79,16 @@
 @property (nonatomic, strong) NSString *urlContact;
 @property (nonatomic, strong) NSString *urlChatStickList;
 @property (nonatomic, strong) NSString *urlChatStick;
+@property (nonatomic, strong) NSString *urlResetLocation;
 
 //sms
 @property (nonatomic, strong) NSString *urlSendCode;
 @property (nonatomic, strong) NSString *urlSendMsg;
 
+
+//payment
+@property (nonatomic, strong) NSString *urlIOSPayment;
+
 @end
 
 @implementation HttpRequest
@@ -91,7 +108,7 @@
     self = [super init];
     if(self)
     {
-        self.urlRoot = @"http://whosay.dashgame.com/";
+        self.urlRoot = @"http://118.31.11.27/";
         
         
         self.urlRegister = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=index&a=register"];
@@ -103,18 +120,23 @@
         
         
         self.urlSocialDataList = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=social&a=lists"];
+        self.urlSocialDelete = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=social&a=delete"];
         self.urlSocialLike = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=social&a=like"];
         self.urlSocialLikeList = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=social&a=like_list"];
         self.urlSocialComment = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=social&a=comment"];
         self.urlSocialCommentList = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=social&a=comment_list"];
         self.urlFollow = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=social&a=follow"];
         self.urlFollowList = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=social&a=follows"];
+        self.urlBefollowedList = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=social&a=befollowed"];
         self.urlUserInfo = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=social&a=get_user"];
         self.urlUpdateNick = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=social&a=update_nick"];
+        self.urlUpdateAlias = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=social&a=update_alias"];
+        self.urlFetchAlias = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=social&a=fetch_alias"];
         self.urlUpdateUserInfo = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=social&a=update_info"];
         self.urlUploadSocialBanner = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=social&a=banner_upload"];
         self.urlNearUser = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=index&a=near_user"];
         self.urlPhotoUpload = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=social&a=photo_upload"];
+        self.urlPhotoDelete = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=social&a=photo_delete"];
         self.urlContact = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=social&a=contact"];
         
         self.urlRequestFriend = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=social&a=request_friend"];
@@ -123,7 +145,10 @@
         self.urlDeleteFriendRequest = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=social&a=delete_request"];
         
         
+        
+        
         self.urlTradePublish = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=trade&a=publish"];
+        self.urlTradePublishCount = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=trade&a=today_count"];
         self.urlTradeEdit = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=trade&a=edit"];
         self.urlTradeDelete = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=trade&a=delete"];
         self.urlTradeDataList = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=trade&a=lists"];
@@ -131,9 +156,11 @@
         self.urlTradeLatestDataList = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=trade&a=latest_lists"];
         self.urlTradeFollow = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=trade&a=follow"];
         self.urlTradeDeleteFollow = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=trade&a=delete_follow"];
+        self.urlTradeInfo = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=trade&a=info"];
         
         
         self.urlChangeMobile = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=index&a=change_mobile"];
+        self.urlForgetPassword = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=index&a=forget"];
         self.urlChangePassword = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=index&a=pwd_update"];
         self.urlFeedBack = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=feedback&a=report"];
         self.urlHobbyList = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=index&a=hobby_list"];
@@ -141,12 +168,20 @@
         self.urlAbout = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=index&a=webview&id=about"];
         self.urlLaw = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=index&a=webview&id=law"];
         self.urlAgreement = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=index&a=webview&id=agreement"];
+        self.urlChatRoomIntro = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=index&a=chatroom_intro"];
         self.urlChatStickList = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=index&a=chatstick_list"];
         self.urlChatStick = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=index&a=chatstick"];
+        self.urlResetLocation = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=index&a=reset_location"];
         
         
         self.urlSendCode = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=index&a=send_code"];
         self.urlSendMsg = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=index&a=send_msg"];
+        
+        self.urlLastSystemMsg = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=index&a=system_msg"];
+        
+        
+        self.urlIOSPayment = [NSString stringWithFormat:@"%@%@", self.urlRoot, @"index.php?m=who&c=index&a=ios_payment"];
+        
     }
     return self;
 }
@@ -211,11 +246,13 @@
         
     } failure:^(NSURLSessionDataTask *task, NSError * error) {
         NSLog(@"请求失败,服务器返回的错误信息%@", error);
-        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:error.description delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
-        [alert showAlertWithCompletionHandler:^(NSInteger index) {
-            if(failure)
-                failure();
-        }];
+//        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:error.description delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
+//        [alert showAlertWithCompletionHandler:^(NSInteger index) {
+//            if(failure)
+//                failure();
+//        }];
+        if(failure)
+            failure();
     }];
     
 }
@@ -248,7 +285,7 @@
     
     [manager POST:URLString parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
         
-        NSData *data = UIImageJPEGRepresentation(image, 1);
+        NSData *data = UIImageJPEGRepresentation(image, Image_Compression_Quality);
         [formData appendPartWithFileData:data name:@"upload" fileName:@"banner.jpg" mimeType:@"image/jpg"];
         
     } progress:uploadProgress success:^(NSURLSessionDataTask *task, id responseObject) {
@@ -390,7 +427,11 @@
         user.districtRoomId = [data valueForKey:@"district_room_id"];
         user.firstTimeJoin = YES;
         
+        user.tradePublishCountUpdateDate = [NSDate date];
         user.tradePublishCount = [[data valueForKey:@"trade_count"] intValue];
+        user.lastSystemMsgId = [[data valueForKey:@"last_sys_msg"] intValue];
+        
+        user.security = [[data valueForKey:@"security"] intValue];
         
         NSMutableArray *tradePriorityItemArr = [data valueForKey:@"trade_priority"];
         [user.tradePriorityItemArr removeAllObjects];
@@ -520,12 +561,14 @@
 
 //social
 - (void)getSocialDataList:(NSString *)lastId
+                 targetId:(NSString *_Nullable)targetId
                   success:(void (^_Nullable)(NSMutableArray *dataList))success
                   failure:(void (^_Nullable)())failure{
     
     NSString *userId = [NSString stringWithFormat:@"%d", [User sharedInfo].userId];
     lastId = lastId ? lastId : @"";
-    NSDictionary *parameters = @{@"user_id":userId, @"last_id":lastId};
+    targetId = targetId ? targetId : @"";
+    NSDictionary *parameters = @{@"user_id":userId, @"last_id":lastId, @"target_id":targetId};
     
     [self request:_urlSocialDataList parameters:parameters progress:nil success:^(id jsonData) {
         
@@ -565,6 +608,26 @@
     
 }
 
+- (void)deleteSocialData:(NSString *_Nullable)socialId
+                 success:(void (^_Nullable)(NSString * _Nullable socialId))success
+                 failure:(void (^_Nullable)())failure{
+    
+    NSString *userId = [NSString stringWithFormat:@"%d", [User sharedInfo].userId];
+    NSDictionary *parameters = @{@"user_id":userId, @"id":socialId};
+    [self request:_urlSocialDelete parameters:parameters progress:nil success:^(id jsonData) {
+        
+        NSString *sid = [jsonData objectForKey:@"id"];
+        [User sharedInfo].hasNewSocial = YES;
+        
+        if(success)
+            success(sid);
+        
+    } failure:^{
+        if(failure)
+            failure();
+    }];
+}
+
 - (void)socialLike:(NSString *)socialId
            success:(void (^_Nullable)(NSString * _Nullable socialId, int currentLikes, NSMutableArray *_Nullable likeList))success
            failure:(void (^_Nullable)())failure{
@@ -733,17 +796,39 @@
     }];
 }
 
+- (void)befollowedList:(void (^_Nullable)(NSMutableArray * _Nullable follows))success
+               failure:(void (^_Nullable)())failure{
+    User *user = [User sharedInfo];
+    NSDictionary *parameters = @{@"user_id":[NSString stringWithFormat:@"%d", user.userId]};
+    
+    [self request:_urlBefollowedList parameters:parameters progress:nil success:^(id jsonData) {
+        
+        if(success)
+            success(jsonData);
+        
+    } failure:^{
+        
+        if(failure)
+            failure();
+        
+    }];
+}
+
 - (void)userInfo:(NSString *_Nullable)userId
+          search:(BOOL *)search
          success:(void (^_Nullable)(UserInfo * _Nullable userInfo))success
          failure:(void (^_Nullable)())failure{
     
     User *user = [User sharedInfo];
     NSDictionary *parameters = @{@"user_id":[NSString stringWithFormat:@"%d", user.userId],
-                                 @"target_id":userId};
+                                 @"target_id":userId,
+                                 @"search":search?@"1":@"0"};
     
     [self request:_urlUserInfo parameters:parameters progress:nil success:^(id jsonData) {
         
         UserInfo *userInfo = [[UserInfo alloc] initWithJson:jsonData];
+        [[User sharedInfo] putUserInfo:userInfo];
+        [[NIMKit sharedKit] setAlias:userId alias:userInfo.alias];
         
         if(success)
             success(userInfo);
@@ -781,6 +866,66 @@
     
 }
 
+- (void)updateAlias:(NSString *_Nonnull)userId
+              alias:(NSString *_Nonnull)alias
+            success:(void (^_Nullable)())success
+            failure:(void (^_Nullable)())failure{
+    User *user = [User sharedInfo];
+    NSDictionary *parameters = @{@"user_id":[NSString stringWithFormat:@"%d", user.userId],
+                                 @"target_id":userId,
+                                 @"alias":alias};
+    
+    [self request:_urlUpdateAlias parameters:parameters progress:nil success:^(id jsonData) {
+        [[NIMKit sharedKit] setAlias:userId alias:alias];
+        if(success)
+            success();
+    } failure:^{
+        if(failure)
+            failure();
+    }];
+}
+
+- (void)fetchAlias:(NSMutableArray *_Nonnull)userIds
+           success:(void (^_Nullable)())success
+           failure:(void (^_Nullable)())failure{
+    User *user = [User sharedInfo];
+    NSDictionary *parameters = @{@"user_id":[NSString stringWithFormat:@"%d", user.userId],
+                                 @"target_ids":userIds};
+    
+    int start = (int)[userIds count] - 1;
+    for(int i=start; i>=0; i--)
+    {
+        NSString *targetId = [userIds objectAtIndex:i];
+        if([[NIMKit sharedKit] hasAlias:targetId])
+        {
+            [userIds removeObjectAtIndex:i];
+        }
+    }
+    
+    if(userIds.count == 0)
+    {
+        if(success)
+            success();
+        return;
+    }
+    
+    [self request:_urlFetchAlias parameters:parameters progress:nil success:^(id jsonData) {
+        
+        NSMutableArray *list = [jsonData objectForKey:@"list"];
+        for(NSDictionary *dict in list)
+        {
+            NSString *targetId = [dict objectForKey:@"target_id"];
+            NSString *alias = [dict objectForKey:@"alias"];
+            
+            [[NIMKit sharedKit] setAlias:targetId alias:alias];
+        }
+        if(success)
+            success();
+    } failure:^{
+        if(failure)
+            failure();
+    }];
+}
 
 - (void)updateUserInfo:(NSMutableDictionary *_Nonnull)info
                success:(void (^_Nullable)())success
@@ -805,6 +950,8 @@
 }
 
 
+
+
 - (void)uploadSocialBanner:(UIImage *_Nullable)image
                    success:(void (^_Nullable)(NSString * _Nullable imgURL))success
                    failure:(void (^_Nullable)())failure{
@@ -869,8 +1016,11 @@
     
     [self uploadImage:_urlPhotoUpload image:image parameters:dict progress:nil success:^(id jsonData) {
         
+        NSMutableDictionary *data = [jsonData mutableCopy];
+        NSString *photoId = [[data objectForKey:@"id"] stringValue];
+        [data setValue:photoId forKey:@"id"];
         if(success)
-            success(jsonData);
+            success(data);
         
     } failure:^{
         if(failure)
@@ -879,6 +1029,20 @@
     
 }
 
+- (void)deletePhoto:(NSString *_Nullable)photoId
+            success:(void (^_Nullable)())success
+            failure:(void (^_Nullable)())failure
+{
+    NSDictionary *dict = @{@"id":photoId};
+    [self request:_urlPhotoDelete parameters:dict progress:nil success:^(id jsonData) {
+        if(success)
+            success();
+    } failure:^{
+        if(failure)
+            failure();
+    }];
+}
+
 
 
 
@@ -990,7 +1154,13 @@
     
     [self request:_urlTradePublish parameters:parameters progress:nil success:^(id jsonData) {
         
+        float coin = [[jsonData objectForKey:@"coin"] floatValue];
+        int tradeId = [[jsonData objectForKey:@"id"] intValue];
+        [User sharedInfo].coin = coin;
+        [User sharedInfo].tradePublishCountUpdateDate = [NSDate date];
         [User sharedInfo].tradePublishCount++;
+        if(!roomId)
+            [User sharedInfo].tradePublishLastId = tradeId;
         
         if(success)
             success();
@@ -1004,6 +1174,34 @@
     
 }
 
+
+- (void)tradePublishCount:(void (^_Nullable)(int count))success
+                  failure:(void (^_Nullable)())failure
+{
+    User *user = [User sharedInfo];
+    NSString *userId = [NSString stringWithFormat:@"%d", user.userId];
+    
+    NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
+    [parameters setValue:userId forKey:@"user_id"];
+    
+    [self request:_urlTradePublishCount parameters:parameters progress:nil success:^(id jsonData) {
+        
+        int count = [[jsonData objectForKey:@"count"] intValue];
+        [User sharedInfo].tradePublishCount = count;
+        [User sharedInfo].tradePublishCountUpdateDate = [NSDate date];
+        
+        if(success)
+            success(count);
+        
+    } failure:^{
+        
+        if(failure)
+            failure();
+        
+    }];
+}
+
+
 - (void)tradeEdit:(NSString *)tradeId
               msg:(NSString *)msg
            picArr:(NSMutableArray *)picArr
@@ -1027,6 +1225,9 @@
         NSMutableArray *picIdArr = [jsonData objectForKey:@"pic_ids"];
         int priority = [[jsonData objectForKey:@"priority"] intValue];
         
+        int coin = [[jsonData objectForKey:@"coin"] intValue];
+        [User sharedInfo].coin = coin;
+        
         if(success)
             success(tradeId, picArr, thumbArr, picIdArr, priority);
         
@@ -1075,12 +1276,16 @@
     User *user = [User sharedInfo];
     
     NSString *province = user.province ? user.province : @"";
+    NSString *city = user.city ? user.city : @"";
+    NSString *district = user.district ? user.district : @"";
     NSString *userId = [NSString stringWithFormat:@"%d", user.userId];
     
     NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
     [parameters setValue:[NSString stringWithFormat:@"%ld", (long)tradeSort] forKey:@"sort"];
     [parameters setValue:[NSString stringWithFormat:@"%d", page] forKey:@"page"];
     [parameters setValue:province forKey:@"province"];
+    [parameters setValue:city forKey:@"city"];
+    [parameters setValue:district forKey:@"district"];
     [parameters setValue:userId forKey:@"user_id"];
     
     
@@ -1262,6 +1467,32 @@
 }
 
 
+- (void)tradeInfo:(NSString *_Nullable)tradeId
+          success:(void (^_Nullable)(TradeData * _Nullable data))success
+          failure:(void (^_Nullable)())failure
+{
+    User *user = [User sharedInfo];
+    NSString *userId = [NSString stringWithFormat:@"%d", user.userId];
+    
+    NSDictionary *parameters = @{@"id":tradeId, @"user_id":userId};
+    
+    [self request:_urlTradeInfo parameters:parameters progress:nil success:^(id jsonData) {
+        
+        TradeData *data = [[TradeData alloc] init];
+        [data setData:jsonData];
+        
+        if(success)
+            success(data);
+        
+    } failure:^{
+        
+        if(failure)
+            failure();
+        
+    }];
+    
+}
+
 
 
 //settings
@@ -1296,6 +1527,37 @@
     
 }
 
+- (void)forgetPassword:(NSString *_Nullable)mobile
+                code:(NSString *_Nullable)code
+           password:(NSString *_Nullable)password
+             success:(void (^_Nullable)())success
+             failure:(void (^_Nullable)())failure{
+    
+    User *user = [User sharedInfo];
+    
+    NSString *userId = [NSString stringWithFormat:@"%d", user.userId];
+    
+    NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
+    [parameters setValue:userId forKey:@"user_id"];
+    [parameters setValue:mobile forKey:@"mobile"];
+    [parameters setValue:code forKey:@"code"];
+    [parameters setValue:password forKey:@"pwd"];
+    
+    
+    [self request:_urlForgetPassword parameters:parameters progress:nil success:^(id jsonData) {
+        
+        if(success)
+            success();
+        
+    } failure:^{
+        
+        if(failure)
+            failure();
+        
+    }];
+    
+}
+
 
 - (void)changePassword:(NSString *_Nullable)pwd
              changePwd:(NSString *_Nullable)changePwd
@@ -1318,6 +1580,8 @@
         if(update)
         {
             NSString *token = [jsonData objectForKey:@"token"];
+            int security = [[jsonData objectForKey:@"security"] intValue];
+            [User sharedInfo].security = security;
             
             LoginData *sdkData = [NTESLoginManager sharedManager].currentLoginData;
             sdkData.token     = token;
@@ -1478,4 +1742,108 @@
           }];
     
 }
+
+
+- (void)chatRoomIntro:(void (^)(NSString * _Nullable intro))success failure:(void (^)())failure
+{
+    NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
+    
+    [self request:_urlChatRoomIntro parameters:parameters progress:nil
+          success:^(id jsonData) {
+              if(success)
+                  success(jsonData);
+          } failure:^{
+              if(failure)
+                  failure();
+          }];
+}
+
+
+- (void)lastSystemMsg:(void (^_Nullable)(NSMutableDictionary * _Nullable data))success
+              failure:(void (^_Nullable)())failure
+{
+    NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
+    
+    [self request:_urlLastSystemMsg parameters:parameters progress:nil
+          success:^(id jsonData) {
+              
+              NSMutableArray *list = [jsonData objectForKey:@"list"];
+              if(success)
+              {
+                  if(list.count > 0)
+                  {
+                      success([list firstObject]);
+                  }
+                  else
+                  {
+                      success(nil);
+                  }
+              }
+          } failure:^{
+              if(failure)
+                  failure();
+          }];
+}
+
+
+- (void)resetLocation:(NSString *)province city:(NSString *)city district:(NSString *)district success:(void (^)())success failure:(void (^)())failure
+{
+    User *user = [User sharedInfo];
+    NSDictionary *parameters = @{@"id":[NSString stringWithFormat:@"%d", user.userId],
+                                 @"province":province,
+                                 @"city":city,
+                                 @"district":district
+                                 };
+    
+    [self request:_urlResetLocation parameters:parameters progress:nil
+          success:^(id jsonData) {
+              
+              user.province = province;
+              user.city = city;
+              user.district = district;
+              
+              user.provinceRoomId = [jsonData objectForKey:@"province"];
+              user.cityRoomId = [jsonData objectForKey:@"city"];
+              user.districtRoomId = [jsonData objectForKey:@"district"];
+              
+              if(success)
+              {
+                  success();
+              }
+          } failure:^{
+              if(failure)
+                  failure();
+          }];
+    
+    
+}
+
+
+
+
+- (void)iosPayment:(NSString *_Nullable)code
+           receipt:(NSString *_Nullable)receipt
+           success:(void (^_Nullable)())success
+           failure:(void (^_Nullable)())failure
+{
+    User *user = [User sharedInfo];
+    NSDictionary *parameters = @{@"user_id":[NSString stringWithFormat:@"%d", user.userId],
+                                 @"code":code,
+                                 @"receipt":receipt
+                                 };
+    [self request:_urlIOSPayment parameters:parameters progress:nil
+          success:^(id jsonData) {
+              
+              user.coin = [[jsonData objectForKey:@"coin"] intValue];
+              
+              if(success)
+              {
+                  success();
+              }
+          } failure:^{
+              if(failure)
+                  failure();
+          }];
+}
+
 @end

+ 0 - 201
NIMDemo/NIMDemo/ImagePagerViewController.m

@@ -1,201 +0,0 @@
-//
-//  ImagePagerViewController.m
-//  NIMDemo
-//
-//  Created by Fenix Wang on 2017/6/28.
-//  Copyright © 2017年 Netease. All rights reserved.
-//
-
-#import "ImagePagerViewController.h"
-#import "UIView+NTES.h"
-#import "UIImageView+WebCache.h"
-#import "SVProgressHUD.h"
-
-
-@interface ImagePagerViewController ()<NIMPageViewDataSource,NIMPageViewDelegate, UIScrollViewDelegate>
-
-@property (nonatomic, strong) NSArray                   *images;
-@property (nonatomic, strong) NSArray                   *thumbs;
-@property (nonatomic, assign) int                       currentIndex;
-
-@property (nonatomic, strong) UIPageControl             *pageControl;
-
-@property (nonatomic, strong) UIScrollView              *scrollView;
-
-@end
-
-@implementation ImagePagerViewController
-
-- (void)viewDidLoad {
-    [super viewDidLoad];
-    // Do any additional setup after loading the view.
-    
-    //self.navigationController.navigationBar.translucent = NO;
-    
-    self.view.backgroundColor = UIColor.blackColor;
-    
-    if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
-        self.edgesForExtendedLayout = UIRectEdgeNone;
-    
-    
-    float startY = [[UIApplication sharedApplication] statusBarFrame].size.height + self.navigationController.navigationBar.frame.size.height;
-    
-    UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.width, self.view.height-startY)];
-    [self.view addSubview:container];
-    
-    _scrollView = [[UIScrollView alloc] initWithFrame:container.bounds];
-    _scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
-    [container addSubview:_scrollView];
-    _scrollView.pagingEnabled = YES;
-    _scrollView.showsVerticalScrollIndicator = NO;
-    _scrollView.showsHorizontalScrollIndicator = NO;
-    _scrollView.delegate = self;
-    _scrollView.scrollsToTop = NO;
-    _scrollView.contentSize = CGSizeMake(_images.count * _scrollView.width, _scrollView.height);
-    
-    
-    _pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(0, container.bottom - 30, container.width, 30)];
-    _pageControl.autoresizingMask = UIViewAutoresizingFlexibleWidth;
-    _pageControl.pageIndicatorTintColor = [UIColor grayColor];
-    _pageControl.currentPageIndicatorTintColor = [UIColor lightGrayColor];
-    _pageControl.hidesForSinglePage = YES;
-    [_pageControl setUserInteractionEnabled:NO];
-    _pageControl.numberOfPages = _images.count;
-    [self.view addSubview:_pageControl];
-    
-
-    
-    
-    for(int i=0; i<_images.count; i++)
-    {
-        UIView *view = [self pageView:i];
-        view.frame = CGRectMake(i*container.width, 0, container.width, container.height);
-        [_scrollView addSubview:view];
-    }
-    
-    CGPoint offset = _scrollView.contentOffset;
-    offset.x = _currentIndex * _scrollView.width;
-    [_scrollView setContentOffset:offset];
-    _pageControl.currentPage = _currentIndex;
-}
-
-- (void)didReceiveMemoryWarning {
-    [super didReceiveMemoryWarning];
-    // Dispose of any resources that can be recreated.
-}
-
-- (void)viewDidAppear:(BOOL)animated{
-    [super viewDidAppear:animated];
-    
-}
-
-
-
-- (UIView *)pageView:(NSInteger)index
-{
-    float width = _scrollView.width;
-    float height = _scrollView.height;
-    
-    UIScrollView *subView = [[UIScrollView alloc] init];
-    
-    NSString *imagePath = [_images objectAtIndex:index];
-    NSString *thumbPath = [_thumbs objectAtIndex:index];
-    NSURL *imageUrl = [NSURL URLWithString:imagePath];
-    NSURL *thumbUrl = [NSURL URLWithString:thumbPath];
-    
-    UIImageView *thumbView = [[UIImageView alloc] initWithFrame:CGRectMake(width/2 - 64, height/2 - 64, 128, 128)];
-    [thumbView sd_setImageWithURL:thumbUrl];
-    [subView addSubview:thumbView];
-    
-    UIActivityIndicatorView* act = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(width/2 - 15, height/2 - 15, 30, 30)];
-    act.activityIndicatorViewStyle=UIActivityIndicatorViewStyleGray;
-    act.color = UIColor.whiteColor;
-    [act startAnimating];
-    
-    [subView addSubview:act];
-    
-    UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
-    [imgView sd_setImageWithURL:imageUrl completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
-        [act stopAnimating];
-    }];
-    imgView.contentMode =  UIViewContentModeScaleAspectFit;
-    imgView.tag = 1;
-    [subView addSubview:imgView];
-    
-    
-    
-    subView.delegate = self;
-    subView.maximumZoomScale = 2.0;
-    subView.minimumZoomScale = 1.0;
-    
-    
-    
-    return subView;
-}
-
-- (void)pageViewScrollEnd: (NIMPageView *)pageView
-             currentIndex: (NSInteger)index
-               totolPages: (NSInteger)pages{
-    
-    self.pageControl.numberOfPages = pages;
-    self.pageControl.currentPage = index;
-}
-
-- (void)scrollViewDidScroll:(UIScrollView *)scrollView
-{
-    if(![scrollView isEqual:_scrollView])
-    {
-        return;
-    }
-    
-    CGFloat width = scrollView.bounds.size.width;
-    CGFloat offsetX = scrollView.contentOffset.x;
-    NSInteger page = (NSInteger)(fabs(offsetX / width));
-    if (page >= 0 && page < [_images count])
-    {
-        if (_currentIndex == page) {
-            return;
-        }
-        _currentIndex = (int)page;
-        _pageControl.currentPage = page;
-    }
-    
-    for(int i=0; i<_images.count; i++)
-    {
-        UIScrollView *view = [_scrollView.subviews objectAtIndex:i];
-        if(i != _currentIndex)
-        {
-            [view setZoomScale:1.0 animated:NO];
-            view.top = 0;
-            view.left = i*_scrollView.width;
-        }
-    }
-}
-
-
-- (void)setImages:(NSArray *)images thumbs:(NSArray *)thumbs startIndex:(int)startIndex{
-    
-    self.images = images;
-    self.thumbs = thumbs;
-    self.currentIndex = startIndex;
-
-}
-
-
--(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
-{
-    if([scrollView isEqual:_scrollView])
-    {
-        return nil;
-    }
-    
-    for(int i=0; i<scrollView.subviews.count; i++)
-    {
-        UIView *view = [scrollView.subviews objectAtIndex:i];
-        if(view.tag == 1)
-            return view;
-    }
-    return nil;
-}
-
-@end

+ 21 - 0
NIMDemo/NIMDemo/Images.xcassets/Whosay/input_border.imageset/Contents.json

@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "filename" : "input_border.png",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}

BIN
NIMDemo/NIMDemo/Images.xcassets/Whosay/input_border.imageset/input_border.png


+ 21 - 0
NIMDemo/NIMDemo/Images.xcassets/Whosay/ss_login_bg.imageset/Contents.json

@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "filename" : "login_bg.png",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}

BIN
NIMDemo/NIMDemo/Images.xcassets/Whosay/ss_login_bg.imageset/login_bg.png


+ 21 - 0
NIMDemo/NIMDemo/Images.xcassets/Whosay/white_bordered_btn.imageset/Contents.json

@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "filename" : "white_bordered_btn.png",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}

BIN
NIMDemo/NIMDemo/Images.xcassets/Whosay/white_bordered_btn.imageset/white_bordered_btn.png


+ 13 - 0
NIMDemo/NIMDemo/IntroViewController.h

@@ -0,0 +1,13 @@
+//
+//  IntroViewController.h
+//  NIMDemo
+//
+//  Created by Fenix Wang on 2017/9/23.
+//  Copyright © 2017年 Netease. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface IntroViewController : UIViewController
+
+@end

+ 129 - 0
NIMDemo/NIMDemo/IntroViewController.m

@@ -0,0 +1,129 @@
+//
+//  IntroViewController.m
+//  NIMDemo
+//
+//  Created by Fenix Wang on 2017/9/23.
+//  Copyright © 2017年 Netease. All rights reserved.
+//
+
+#import "IntroViewController.h"
+#import "UIView+NIM.h"
+#import "AppDelegate.h"
+
+@interface IntroViewController ()<UIScrollViewDelegate>
+@property (weak, nonatomic) IBOutlet UIButton   *skipBtn;
+@property (weak, nonatomic) IBOutlet UIButton   *startBtn;
+@property (weak, nonatomic) IBOutlet UIView     *pagerContainer;
+
+@property (nonatomic, strong) UIScrollView      *scrollView;
+@property (nonatomic, assign) int               count;
+
+@end
+
+@implementation IntroViewController
+
+- (void)viewDidLoad {
+    [super viewDidLoad];
+    // Do any additional setup after loading the view.
+    
+    _skipBtn.layer.cornerRadius = 5;
+    _startBtn.layer.cornerRadius = 25;
+    
+    _scrollView = [[UIScrollView alloc] initWithFrame:_pagerContainer.bounds];
+    _scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
+    [_pagerContainer addSubview:_scrollView];
+    _scrollView.pagingEnabled = YES;
+    _scrollView.showsVerticalScrollIndicator = NO;
+    _scrollView.showsHorizontalScrollIndicator = NO;
+    _scrollView.delegate = self;
+    _scrollView.scrollsToTop = NO;
+    
+    _count = 3;
+    
+    [self layoutPics];
+}
+
+- (void)didReceiveMemoryWarning {
+    [super didReceiveMemoryWarning];
+    // Dispose of any resources that can be recreated.
+}
+
+
+
+- (void)layoutPics{
+    
+    UIImageView *imageView = [[UIImageView alloc] init];
+    [imageView setImage:[UIImage imageNamed:@"tuto-1-min"]];
+    [imageView setContentMode:UIViewContentModeScaleAspectFill];
+    imageView.frame = CGRectMake(0 * _scrollView.nim_width, 0, _scrollView.nim_width, _scrollView.nim_height);
+    [_scrollView addSubview:imageView];
+    
+    
+    imageView = [[UIImageView alloc] init];
+    [imageView setImage:[UIImage imageNamed:@"tuto-2-min"]];
+    [imageView setContentMode:UIViewContentModeScaleAspectFill];
+    imageView.frame = CGRectMake(1 * _scrollView.nim_width, 0, _scrollView.nim_width, _scrollView.nim_height);
+    [_scrollView addSubview:imageView];
+    
+    
+    imageView = [[UIImageView alloc] init];
+    [imageView setImage:[UIImage imageNamed:@"tuto-3-min"]];
+    [imageView setContentMode:UIViewContentModeScaleAspectFill];
+    imageView.frame = CGRectMake(2 * _scrollView.nim_width, 0, _scrollView.nim_width, _scrollView.nim_height);
+    [_scrollView addSubview:imageView];
+    
+    
+    
+    _scrollView.contentSize = CGSizeMake(_count * _scrollView.nim_width, _scrollView.nim_height);
+    CGPoint offset = _scrollView.contentOffset;
+    offset.x = 0 * _scrollView.nim_width;
+    [_scrollView setContentOffset:offset];
+    
+    [self setCurrentPage:0];
+}
+
+- (void)scrollViewDidScroll:(UIScrollView *)scrollView
+{
+    CGFloat width = scrollView.bounds.size.width;
+    CGFloat offsetX = scrollView.contentOffset.x;
+    NSInteger page = (NSInteger)(fabs(offsetX / width));
+    
+    [self setCurrentPage:page];
+}
+
+- (void)setCurrentPage:(NSInteger)page{
+    if(page == _count - 1)
+    {
+        _startBtn.hidden = NO;
+        _skipBtn.hidden = YES;
+    }
+    else
+    {
+        _startBtn.hidden = YES;
+        _skipBtn.hidden = NO;
+    }
+}
+
+
+- (IBAction)onTouchSkip:(id)sender {
+    [self close];
+}
+
+- (IBAction)onTouchStart:(id)sender {
+    [self close];
+}
+
+- (void)close{
+    
+    //存入数组并同步
+    NSMutableArray *introArr = [[NSMutableArray alloc] init];
+    
+    [[NSUserDefaults standardUserDefaults] setObject:introArr forKey:@"ShowIntroFlag"];
+    [[NSUserDefaults standardUserDefaults] synchronize];
+    
+    UIStoryboard *board = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
+    UINavigationController *nav = [board instantiateViewControllerWithIdentifier:@"NavController"];
+    
+    [[UIApplication sharedApplication] keyWindow].rootViewController = nav;
+}
+@end

+ 11 - 0
NIMDemo/NIMDemo/LocationManager.m

@@ -129,6 +129,17 @@
 }
 
 - (void)toTabBarView{
+    
+    [[User sharedInfo] requestGiftList:^(NSMutableArray * _Nullable list) {
+        [self showTabBarView];
+    } failure:^(NSError * _Nullable error) {
+        [self showTabBarView];
+    }];
+    
+}
+
+- (void)showTabBarView
+{
     UIStoryboard *board = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
     UIViewController *next = [board instantiateViewControllerWithIdentifier:@"TabBarView"];
     

+ 66 - 2
NIMDemo/NIMDemo/LoginViewController.m

@@ -16,10 +16,16 @@
 #import "UIView+Toast.h"
 #import "HttpRequest.h"
 #import "LocationManager.h"
+#import "ForgetTableViewController.h"
+#import "NTESService.h"
+#import "NTESLoginManager.h"
 
 @interface LoginViewController ()
 @property (weak, nonatomic) IBOutlet UITextField *mobileTextField;
 @property (weak, nonatomic) IBOutlet UITextField *pwdTextField;
+@property (unsafe_unretained, nonatomic) IBOutlet UIButton *agreeBtn;
+
+@property (nonatomic, assign) BOOL isAgree;
 
 @end
 
@@ -29,7 +35,8 @@
     [super viewDidLoad];
     // Do any additional setup after loading the view.
     
-    self.navigationItem.title = @"登录";
+    _isAgree = YES;
+    [_agreeBtn setImage:[UIImage imageNamed:@"聊天3_05"] forState:UIControlStateNormal];
 }
 
 - (void)didReceiveMemoryWarning {
@@ -40,7 +47,35 @@
 -(void) viewWillAppear:(BOOL)animated{
     [super viewWillAppear:animated];
     AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
-    [appDelegate whiteNavBar:self];
+    [appDelegate transparentNavBar:self];
+    
+    
+    LoginData *data = [[NTESLoginManager sharedManager] currentLoginData];
+    NSString *account = [data account];
+    NSString *token = [data token];
+    
+    //如果有缓存用户名密码推荐使用自动登录
+    if ([account length] && [token length])
+    {
+        [SVProgressHUD show];
+        
+        NIMAutoLoginData *loginData = [[NIMAutoLoginData alloc] init];
+        loginData.account = account;
+        loginData.token = token;
+        
+        [[[NIMSDK sharedSDK] loginManager] autoLogin:loginData];
+        [[NTESServiceManager sharedManager] start];
+        
+        [[HttpRequest shared] loginAccount:account password:token success:^{
+            [[LocationManager sharedManager] relocationWhenEnter];
+        } failure:^{
+            [SVProgressHUD dismiss];
+        }];
+    }
+    else
+    {
+        //[self setupLoginViewController];
+    }
 }
 
 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
@@ -61,6 +96,15 @@
 */
 
 - (IBAction)logicClick:(id)sender {
+    
+    if(!_isAgree)
+    {
+        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"您需要同意遵守《谁说社交APP服务协议》" message:nil delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
+        [alert show];
+        return;
+    }
+    
+    
     NSString *mobile = self.mobileTextField.text;
     NSString *pwd = self.pwdTextField.text;
     
@@ -88,4 +132,24 @@
     [[LocationManager sharedManager] relocationWhenEnter];
 }
 
+- (IBAction)toggleAgreeBtn:(id)sender {
+    
+    _isAgree = !_isAgree;
+    if(_isAgree)
+    {
+        [_agreeBtn setImage:[UIImage imageNamed:@"聊天3_05"] forState:UIControlStateNormal];
+    }
+    else
+    {
+        [_agreeBtn setImage:[UIImage imageNamed:@"聊天3_03"] forState:UIControlStateNormal];
+    }
+}
+
+
+- (IBAction)forgetPassword:(id)sender {
+    UIStoryboard *board = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
+    UIViewController *vc = [board instantiateViewControllerWithIdentifier:@"Forget"];
+    [self.navigationController pushViewController:vc animated:YES];
+}
+
 @end

+ 46 - 33
NIMDemo/NIMDemo/MyUserInfoViewController.m

@@ -18,6 +18,7 @@
 #import "UIImage+NTES.h"
 #import "HttpRequest.h"
 #import "HobbyViewController.h"
+#import "CityPickerViewController.h"
 
 @interface MyUserInfoViewController ()<UINavigationControllerDelegate, UIImagePickerControllerDelegate>
 
@@ -81,6 +82,8 @@
     if(!_avatar)
     {
         _avatar = [[NIMAvatarImageView alloc] initWithFrame:CGRectMake(0, 0, _avatarContainer.width, _avatarContainer.height)];
+        [_avatar setUserInteractionEnabled:YES];
+        [_avatar addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleAvatar:)]];
         [_avatarContainer addSubview:_avatar];
     }
     NSURL *url = user.userInfo && user.userInfo.avatarUrl ? [NSURL URLWithString:user.userInfo.avatarUrl] : nil;
@@ -92,18 +95,11 @@
     else if(user.userInfo.gender == NIMUserGenderFemale)
         _genderLabel.text = @"女";
     else if(user.userInfo.gender == NIMUserGenderUnknown)
-        _genderLabel.text = @"其他";
+        _genderLabel.text = @"保密";
     
-    if(_userInfo.city && _userInfo.district && _userInfo.city.length > 0 && _userInfo.district.length > 0)
+    if(_userInfo.address && _userInfo.address.length > 0)
     {
-        if([_userInfo.city isEqualToString:_userInfo.district])
-        {
-            _localLabel.text = _userInfo.district;
-        }
-        else
-        {
-            _localLabel.text = [NSString stringWithFormat:@"%@%@", _userInfo.city, _userInfo.district];
-        }
+        _localLabel.text = _userInfo.address;
     }
     else
     {
@@ -130,12 +126,20 @@
     
     
     if(_userInfo.realName && _userInfo.realName.length > 0)
-        _realNameLabel.text = _userInfo.realName;
+    {
+        NSString *lastName = [_userInfo.realName substringFromIndex:_userInfo.realName.length-1];
+        NSString *realName = [NSString stringWithFormat:@"***********%@", lastName];
+        _realNameLabel.text = [realName substringFromIndex:(realName.length-_userInfo.realName.length)];
+    }
     else
         _realNameLabel.text = _realNamePlaceHold;
     
-    if(_userInfo.idNumber && _userInfo.idNumber.length > 0)
-        _idNumberLabel.text = _userInfo.idNumber;
+    if(_userInfo.idNumber && _userInfo.idNumber.length > 6)
+    {
+        NSString *lastId = [_userInfo.idNumber substringFromIndex:_userInfo.idNumber.length-6];
+        NSString *idNumber = [NSString stringWithFormat:@"*********************%@", lastId];
+        _idNumberLabel.text = [idNumber substringFromIndex:(idNumber.length-_userInfo.idNumber.length)];
+    }
     else
         _idNumberLabel.text = _idNumberPlaceHold;
 }
@@ -152,7 +156,7 @@
     switch(cell.tag)
     {
         case 1:
-            [self handleAvatar];
+            [self handleAvatar:nil];
             break;
         case 2:
             [self handleNick];
@@ -160,6 +164,9 @@
         case 3:
             [self handleGender];
             break;
+        case 4:
+            [self handleAddress];
+            break;
         case 6:
             [self handleAge];
             break;
@@ -178,7 +185,7 @@
 }
 
 
-- (void)handleAvatar{
+- (void)handleAvatar:(id)sender{
     if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
         UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"设置头像" delegate:nil cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"拍照",@"从相册", nil];
         [sheet showInView:self.view completionHandler:^(NSInteger index) {
@@ -262,10 +269,6 @@
 }
 
 
-
-
-
-
 - (void)handleNick{
     _nickAlert = [[UIAlertView alloc] initWithTitle:@"" message:@"修改昵称" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确认", nil];
     _nickAlert.alertViewStyle = UIAlertViewStylePlainTextInput;
@@ -273,7 +276,7 @@
 }
 
 - (void)handleGender{
-    UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"设置性别" delegate:nil cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"男",@"女",@"其他", nil];
+    UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"设置性别" delegate:nil cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"男",@"女",@"保密", nil];
     [sheet showInView:self.view completionHandler:^(NSInteger index) {
         
         NIMUserGender gender = NIMUserGenderUnknown;
@@ -311,6 +314,13 @@
     }];
 }
 
+- (void)handleAddress{
+    UIStoryboard *board = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
+    CityPickerViewController *vc = [board instantiateViewControllerWithIdentifier:@"CityPicker"];
+    vc.isChangeAddress = YES;
+    [self.navigationController pushViewController:vc animated:YES];
+}
+
 - (void)handleAge{
     _ageAlert = [[UIAlertView alloc] initWithTitle:@"" message:@"修改年龄" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确认", nil];
     _ageAlert.alertViewStyle = UIAlertViewStylePlainTextInput;
@@ -400,19 +410,22 @@
             if (nick.length) {
                 [SVProgressHUD show];
                 __weak typeof(self) wself = self;
-                [[NIMSDK sharedSDK].userManager updateMyUserInfo:@{@(NIMUserInfoUpdateTagNick) : nick} completion:^(NSError *error) {
-                    [SVProgressHUD dismiss];
-                    if (!error) {
-                        [wself.view makeToast:@"昵称设置成功"
-                                                          duration:2
-                                                          position:CSToastPositionCenter];
-                        [[HttpRequest shared] updateNick:nick success:nil failure:nil];
-                        [wself fillInfo];
-                    }else{
-                        [wself.view makeToast:@"昵称设置失败,请重试"
-                                     duration:2
-                                     position:CSToastPositionCenter];
-                    }
+                [[HttpRequest shared] updateNick:nick success:^{
+                    [[NIMSDK sharedSDK].userManager updateMyUserInfo:@{@(NIMUserInfoUpdateTagNick) : nick} completion:^(NSError *error) {
+                        [SVProgressHUD dismiss];
+                        if (!error) {
+                            [wself.view makeToast:@"昵称设置成功"
+                                         duration:2
+                                         position:CSToastPositionCenter];
+                            [wself fillInfo];
+                        }else{
+                            [wself.view makeToast:@"昵称设置失败,请重试"
+                                         duration:2
+                                         position:CSToastPositionCenter];
+                        }
+                    }];
+                } failure:^{
+                    
                 }];
             }
             else

+ 4 - 0
NIMDemo/NIMDemo/PSCityPickerView/PSCityPickerView.m

@@ -86,6 +86,7 @@
     }
     else
     {
+        self.province = province;
         int row = 0;
         NSArray *provinceArr = self.provinceArr;
         for(int i=0; i<provinceArr.count; i++)
@@ -107,6 +108,7 @@
     }
     else
     {
+        self.city = city;
         int row = 0;
         NSMutableArray *cityArr = [self cityNamesInProvinceDic:self.currentProvinceDic];
         for(int i=0; i<cityArr.count; i++)
@@ -128,6 +130,7 @@
     }
     else
     {
+        self.district = district;
         int row = 0;
         NSArray *districtArr = [self districtArrayInCityDic:self.currentCityDic];
         for(int i=0; i<districtArr.count; i++)
@@ -157,6 +160,7 @@
         self.cityArr = cityNames;
     
         NSDictionary *cityDic = [self provinceDic:provinceDic cityDicAtIndex:FIRST_INDEX];
+        self.currentCityDic = cityDic;
         NSArray *districtNames = [self districtArrayInCityDic:cityDic];
         self.districtArr = districtNames;
         

+ 4 - 2
NIMDemo/NIMDemo/PayOptionViewController.m

@@ -11,6 +11,7 @@
 #import <AlipaySDK/AlipaySDK.h>
 #import "Order.h"
 #import "RSADataSigner.h"
+#import "UIView+Toast.h"
 
 @interface PayOptionViewController ()
 @property (weak, nonatomic) IBOutlet UILabel *moneyLabel;
@@ -45,7 +46,7 @@
 }
 
 - (IBAction)onTouchWXPay:(id)sender {
-    
+    [self.view makeToast:@"功能暂未开放" duration:2.0 position:CSToastPositionCenter];
 }
 
 - (IBAction)onTouchAliPay:(id)sender {
@@ -96,7 +97,8 @@
     order.biz_content.subject = [NSString stringWithFormat:@"谁说充值,获取%d说币", _money];
     order.biz_content.out_trade_no = [self generateTradeNO]; //订单ID(由商家自行制定)
     order.biz_content.timeout_express = @"30m"; //超时时间设置
-    order.biz_content.total_amount = [NSString stringWithFormat:@"%.2f", 0.01]; //商品价格
+    //order.biz_content.total_amount = [NSString stringWithFormat:@"%.2f", 0.01]; //商品价格
+    order.biz_content.total_amount = [NSString stringWithFormat:@"%.2f", _money]; //商品价格
     
     //将商品信息拼接成字符串
     NSString *orderInfo = [order orderInfoEncoded:NO];

+ 140 - 11
NIMDemo/NIMDemo/RechargeViewController.m

@@ -11,6 +11,11 @@
 #import "UIView+NIM.h"
 #import "User.h"
 #import "PayOptionViewController.h"
+#import <StoreKit/StoreKit.h>
+#import <Foundation/Foundation.h>
+#import "SVProgressHUD.h"
+#import "HttpRequest.h"
+#import "UIView+Toast.h"
 
 @interface RechargeViewController ()<RechargeItemTouchDelegate>
 
@@ -18,6 +23,9 @@
 @property (nonatomic, strong) NSDictionary *currentData;
 @property (nonatomic, strong) NSMutableArray *itemViews;
 
+@property (nonatomic, strong) NSArray<SKProduct *> *products;
+@property (nonatomic, strong) NSString *readyToPayCode;
+
 @end
 
 @implementation RechargeViewController
@@ -28,12 +36,12 @@
     self.view.backgroundColor = UIColor.whiteColor;
     
     _datas = [[NSMutableArray alloc] init];
-    [_datas addObject:@{@"id":@"1", @"title":@"20元", @"desc":@"20说币", @"num":@"20"}];
-    [_datas addObject:@{@"id":@"2", @"title":@"30元", @"desc":@"30说币", @"num":@"30"}];
-    [_datas addObject:@{@"id":@"3", @"title":@"50元", @"desc":@"50说币", @"num":@"50"}];
-    [_datas addObject:@{@"id":@"4", @"title":@"100元", @"desc":@"100说币", @"num":@"100"}];
-    [_datas addObject:@{@"id":@"5", @"title":@"200元", @"desc":@"200说币", @"num":@"200"}];
-    [_datas addObject:@{@"id":@"6", @"title":@"300元", @"desc":@"300说币", @"num":@"300"}];
+    [_datas addObject:@{@"id":@"1", @"title":@"28元", @"desc":@"28说币", @"num":@"28", @"code":@"com.sheishuo.app.cny28"}];
+    [_datas addObject:@{@"id":@"2", @"title":@"68元", @"desc":@"68说币", @"num":@"68", @"code":@"com.sheishuo.app.cny68"}];
+    [_datas addObject:@{@"id":@"3", @"title":@"98元", @"desc":@"98说币", @"num":@"98", @"code":@"com.sheishuo.app.cny98"}];
+    [_datas addObject:@{@"id":@"4", @"title":@"188元", @"desc":@"188说币", @"num":@"188", @"code":@"com.sheishuo.app.cny188"}];
+    [_datas addObject:@{@"id":@"5", @"title":@"288元", @"desc":@"288说币", @"num":@"288", @"code":@"com.sheishuo.app.cny288"}];
+    [_datas addObject:@{@"id":@"6", @"title":@"388元", @"desc":@"388说币", @"num":@"388", @"code":@"com.sheishuo.app.cny388"}];
     
     
     _itemViews = [[NSMutableArray alloc] init];
@@ -63,8 +71,29 @@
     [self.view addSubview:rechargeBtn];
     
     [self selectedItem:[_datas objectAtIndex:0]];
+    
+    
+    [[SKPaymentQueue defaultQueue] addTransactionObserver:(id)self];
+    [self fetchProducts];
+}
+
+
+-(void)fetchProducts{
+    
+    NSMutableArray *idArr = [[NSMutableArray alloc] init];
+    for(NSDictionary *item in _datas)
+    {
+        NSString *code = [item objectForKey:@"code"];
+        [idArr addObject:code];
+    }
+    
+    SKProductsRequest *request = [[SKProductsRequest alloc]initWithProductIdentifiers:[NSSet setWithArray:idArr]];
+    request.delegate = (id)self;
+    [request start];
+    
 }
 
+
 - (void)didReceiveMemoryWarning {
     [super didReceiveMemoryWarning];
     // Dispose of any resources that can be recreated.
@@ -87,13 +116,113 @@
 
 - (void)doRecharge:(int)sender
 {
-    UIStoryboard *board = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
-    PayOptionViewController *payOptionVC = [board instantiateViewControllerWithIdentifier:@"PayOption"];
-    int money = [[_currentData objectForKey:@"num"] intValue];
-    [payOptionVC setMoney:money];
-    [self.navigationController pushViewController:payOptionVC animated:YES];
+//    UIStoryboard *board = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
+//    PayOptionViewController *payOptionVC = [board instantiateViewControllerWithIdentifier:@"PayOption"];
+//    int money = [[_currentData objectForKey:@"num"] intValue];
+//    [payOptionVC setMoney:money];
+//    [self.navigationController pushViewController:payOptionVC animated:YES];
+    
+    [SVProgressHUD show];
+    
+    NSString *pid = [_currentData objectForKey:@"code"];
+    
+    if(_products && _products.count > 0)
+    {
+        for (SKProduct *product in _products)
+        {
+            NSLog(@"Check product %@ %@", pid, product.productIdentifier);
+            if([product.productIdentifier isEqualToString:pid])
+            {
+                SKPayment *payment = [SKPayment paymentWithProduct:product];
+                [[SKPaymentQueue defaultQueue]addPayment:payment];
+                NSLog(@"Buy %@", product.productIdentifier);
+                break;
+            }
+        }
+        _readyToPayCode = nil;
+    }
+    else
+    {
+        _readyToPayCode = pid;
+    }
+}
+
+-(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(nonnull SKProductsResponse *)response{
+    
+    _products = response.products;
+    for (SKProduct *product in _products) {
+        NSLog(@"Product %@ %@", product.productIdentifier, product.price.stringValue);
+    }
     
+    if(_readyToPayCode)
+    {
+        [self doRecharge:nil];
+    }
+}
+
+-(void)request:(SKRequest *)request didFailWithError:(nonnull NSError *)error{
+    
+    NSLog(@"%@", error);
+    
+}
+
+-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(nonnull NSArray<SKPaymentTransaction *> *)transactions{
+    
+    for (SKPaymentTransaction *tx in transactions) {
+        switch (tx.transactionState) {
+            case SKPaymentTransactionStatePurchased:
+                [[SKPaymentQueue defaultQueue]finishTransaction:tx];
+                [self paymentSuccess:tx];
+                break;
+                
+            case SKPaymentTransactionStateFailed:
+                [[SKPaymentQueue defaultQueue]finishTransaction:tx];
+                NSLog(@"Error: %@", tx.error);
+                [self paymentFailed:tx];
+                break;
+                
+            case SKPaymentTransactionStateRestored:
+                [[SKPaymentQueue defaultQueue]finishTransaction:tx];
+                NSLog(@"SKPaymentTransactionStateRestored");
+                break;
+            default:
+                break;
+        }
+    }
+    
+}
+
+
+
+-(void)paymentSuccess:(SKPaymentTransaction *)tx{
+    
+    [SVProgressHUD dismiss];
+    
+    NSData *receiptData;
+    if (NSFoundationVersionNumber >= NSFoundationVersionNumber_iOS_7_0) {
+        NSLog(@"ReceiptData later iOS 7");
+        receiptData = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] appStoreReceiptURL]];
+    } else {
+        NSLog(@"ReceiptData earlier iOS 7");
+        receiptData = tx.transactionReceipt;
+    }
+    
+    NSString *itemId = tx.payment.productIdentifier;
+    NSString *receiptStr = [receiptData base64EncodedStringWithOptions:0];
+    NSLog(@"SKPaymentTransactionStatePurchased %@", receiptStr);
+    
+    [[HttpRequest shared] iosPayment:itemId receipt:receiptStr success:^{
+        [self.view makeToast:@"支付成功" duration:2.0 position:CSToastPositionCenter];
+    } failure:^{
+        [self.view makeToast:@"支付失败" duration:2.0 position:CSToastPositionCenter];
+    }];
+    
+}
+
+-(void)paymentFailed:(SKPaymentTransaction *)tx{
     
+    [SVProgressHUD dismiss];
+    [self.view makeToast:@"支付失败" duration:2.0 position:CSToastPositionCenter];
 }
 
 @end

+ 10 - 3
NIMDemo/NIMDemo/RegisterViewController.m

@@ -55,7 +55,7 @@
 -(void) viewWillAppear:(BOOL)animated{
     [super viewWillAppear:animated];
     AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
-    [appDelegate whiteNavBar:self];
+    [appDelegate orangeNavBar:self];
     
     self.navigationItem.title = @"注册";
 }
@@ -122,7 +122,7 @@
     [self.view addSubview:pwdBorder];
     
     _pwdTextField = [[UITextField alloc] initWithFrame:CGRectMake(pwdBorder.left+padding, pwdBorder.top+padding, pwdBorder.width-padding*2, pwdBorder.height-padding*2)];
-    _pwdTextField.placeholder = @"密码 (6-12位数字、字母和符号组成)";
+    _pwdTextField.placeholder = @"密码 (8位以上数字、字母和符号组成)";
     [self.view addSubview:_pwdTextField];
     
     
@@ -172,7 +172,7 @@
     
     UILabel *copyRight = [[UILabel alloc] initWithFrame:CGRectMake(startX, self.view.bottom-50, width, 20)];
     [copyRight setTextColor:UIColor.lightGrayColor];
-    [copyRight setText:@"谁说APP@版权所有"];
+    [copyRight setText:@"谁说APP©版权所有"];
     copyRight.font = [UIFont systemFontOfSize:12];
     copyRight.textAlignment = NSTextAlignmentCenter;
     [self.view addSubview:copyRight];
@@ -257,6 +257,13 @@
     NSString *password = self.pwdTextField.text;
     NSString *code = self.vcTextField.text;
     
+    if([password length] < Password_Min_Length)
+    {
+        NSString *title = [NSString stringWithFormat:@"密码长度至少需要%d个字符", Password_Min_Length];
+        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:nil delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
+        [alert show];
+        return;
+    }
     
     [SVProgressHUD show];
     [[HttpRequest shared] registerAccount:mobile code:code password:password success:^{

+ 12 - 1
NIMDemo/NIMDemo/SectionGroup/GroupDescTableViewCell.m

@@ -9,6 +9,7 @@
 #import "GroupDescTableViewCell.h"
 #import "UIView+NTES.h"
 #import "GroupIntroViewController.h"
+#import "User.h"
 
 @interface GroupDescTableViewCell()
 
@@ -54,7 +55,17 @@
     
     _titleLabel.text = [data objectForKey:@"title"];
     NIMTeam *team = [data objectForKey:@"value"];
-    _descTextView.text = team.intro ? team.intro : @"";
+    if([[User sharedInfo] isSystemTeam:team.teamId])
+    {
+        __weak typeof(self) wself = self;
+        [[User sharedInfo] fetchChatRoomIntro:^(NSString * _Nullable intro) {
+            wself.descTextView.text = intro;
+        }];
+    }
+    else
+    {
+        _descTextView.text = team.intro ? team.intro : @"";
+    }
     
 }
 

+ 82 - 3
NIMDemo/NIMDemo/SectionGroup/GroupMenberTableViewCell.m

@@ -10,10 +10,17 @@
 #import "NIMSDK/NIMSDK.h"
 #import "GroupMenberIcon.h"
 #import "UIView+NTES.h"
+#import "NIMContactSelectViewController.h"
+#import "UIView+Toast.h"
+#import "User.h"
 
-@interface GroupMenberTableViewCell()
+@interface GroupMenberTableViewCell()<NIMContactSelectDelegate>
 
 @property (nonatomic, strong) UIView            *container;
+@property (nonatomic, strong) NIMTeam           *team;
+@property (nonatomic, strong) NSArray           *members;
+
+@property (nonatomic, strong) UIButton          *addBtn;
 
 @end
 
@@ -40,21 +47,48 @@
 
 - (void)setData:(NSDictionary *)data{
     
+    _team = [data objectForKey:@"team"];
+    _members = [data objectForKey:@"list"];
+    
     int numInRow = 6;
     float space = 5;
     float size = (_container.width - space * (numInRow - 1)) / numInRow;
+    int index = 0;
+    
+    BOOL isTeamOwner = [[User sharedInfo] isTeamOwner:_team];
+    if(isTeamOwner)
+    {
+        if(!_addBtn)
+        {
+            _addBtn = [UIButton buttonWithType:UIButtonTypeCustom];
+            [_addBtn setImage:[UIImage imageNamed:@"icon_add_normal"] forState:UIControlStateNormal];
+            _addBtn.frame = CGRectMake(0, _container.centerY-size/2, size, size);
+            [_addBtn addTarget:self action:@selector(onTouchAdd:) forControlEvents:UIControlEventTouchUpInside];
+            [_container addSubview:_addBtn];
+        }
+        _addBtn.hidden = NO;
+        index++;
+    }
+    else
+    {
+        if(_addBtn)
+        {
+            _addBtn.hidden = YES;
+        }
+    }
     
     NSArray *list = [data objectForKey:@"list"];
     for(int i=0; i<list.count; i++)
     {
-        float startX = (size + space) * i;
+        float startX = (size + space) * index;
         NIMTeamMember *member = [list objectAtIndex:i];
         
         GroupMenberIcon *icon = [[GroupMenberIcon alloc] initWithFrame:CGRectMake(startX, _container.centerY-size/2, size, size)];
         [icon setMenber:member];
         [_container addSubview:icon];
         
-        if(i >= numInRow)
+        index++;
+        if(index >= numInRow)
         {
             break;
         }
@@ -62,6 +96,51 @@
     
 }
 
+- (void)onTouchAdd:(id)sender{
+    [self didSelectAddOpeartor];
+}
+
+- (void)didSelectAddOpeartor{
+    NSMutableArray *users = [[NSMutableArray alloc] init];
+    for (NIMTeamMember *member in _members) {
+        [users addObject:member.userId];
+    }
+    NSString *currentUserID = [[[NIMSDK sharedSDK] loginManager] currentAccount];
+    [users addObject:currentUserID];
+    
+    NIMContactFollowSelectConfig *config = [[NIMContactFollowSelectConfig alloc] init];
+    config.filterIds = users;
+    config.needMutiSelected = YES;
+    NIMContactSelectViewController *vc = [[NIMContactSelectViewController alloc] initWithConfig:config];
+    vc.delegate = self;
+    [vc show];
+}
+
+
+#pragma mark - ContactSelectDelegate
+- (void)didFinishedSelect:(NSArray *)selectedContacts{
+    if (!selectedContacts.count) {
+        return;
+    }
+    
+    NSString *postscript = @"邀请你加入群组";
+    [[NIMSDK sharedSDK].teamManager addUsers:selectedContacts toTeam:self.team.teamId postscript:postscript completion:^(NSError *error, NSArray *members) {
+        if (!error) {
+            [self makeToast:@"邀请成功"
+                        duration:2
+                        position:CSToastPositionCenter];
+        }else{
+            [self makeToast:[NSString stringWithFormat:@"邀请失败 code:%zd",error.code]
+                        duration:2
+                        position:CSToastPositionCenter];
+        }
+    }];
+}
+
+- (void)didCancelledSelect{
+    
+}
+
 
 
 

+ 3 - 0
NIMDemo/NIMDemo/SectionSetting/AddPhotoViewController.h

@@ -7,7 +7,10 @@
 //
 
 #import <UIKit/UIKit.h>
+#import "UserInfo.h"
 
 @interface AddPhotoViewController : UIViewController
 
+- (void)setUserInfo:(UserInfo *)userInfo;
+
 @end

+ 147 - 14
NIMDemo/NIMDemo/SectionSetting/AddPhotoViewController.m

@@ -16,6 +16,8 @@
 #import "HttpRequest.h"
 #import "User.h"
 #import "SVProgressHUD.h"
+#import "ImagePagerViewController.h"
+#import "UIAlertView+NTESBlock.h"
 
 @interface AddPhotoViewController ()
 
@@ -31,6 +33,10 @@
 @property (nonatomic, strong) NSMutableArray        *photoArr;
 @property (nonatomic, strong) NSMutableArray        *imgViewArr;
 
+@property (nonatomic, strong) UserInfo              *userInfo;
+
+@property (nonatomic, strong) UIButton              *editBtn;
+@property (nonatomic, assign) BOOL                  isEditing;
 @end
 
 @implementation AddPhotoViewController
@@ -48,9 +54,17 @@
     _imgColumns = 3;
     _imgSize = (self.view.width - _imgSpace * 2) / _imgColumns;
     
-    _photoArr = [[User sharedInfo].userInfo.photeArr mutableCopy];
+    if(_userInfo)
+    {
+        _photoArr = [_userInfo.photeArr mutableCopy];
+        [self fillImages];
+    }
+    else
+    {
+        _photoArr = [[User sharedInfo].userInfo.photeArr mutableCopy];
+        [self fillImages];
+    }
     
-    [self fillImages];
 }
 
 - (void)didReceiveMemoryWarning {
@@ -61,9 +75,44 @@
 - (void)viewWillAppear:(BOOL)animated{
     [super viewWillAppear:animated];
     
-    [self.navigationItem setTitle:@"添加照片"];
+    if(_userInfo)
+    {
+        [self.navigationItem setTitle:@"动态"];
+    }
+    else
+    {
+        [self.navigationItem setTitle:@"添加照片"];
+        _editBtn = [UIButton buttonWithType:UIButtonTypeCustom];
+        [_editBtn setTitle:@"编辑" forState:UIControlStateNormal];
+        [_editBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
+        [_editBtn addTarget:self action:@selector(onTouchEdit:) forControlEvents:UIControlEventTouchUpInside];
+        [_editBtn sizeToFit];
+        
+        UIBarButtonItem *rightItem = [[UIBarButtonItem alloc] initWithCustomView:_editBtn];
+        [self.navigationItem setRightBarButtonItems:@[rightItem]];
+    }
+}
+
+- (void)onTouchEdit:(id)sender{
+    
+    if(_isEditing)
+    {
+        _isEditing = NO;
+        [_editBtn setTitle:@"编辑" forState:UIControlStateNormal];
+        [self fillImages];
+    }
+    else
+    {
+        _isEditing = YES;
+        [_editBtn setTitle:@"完成" forState:UIControlStateNormal];
+        [self fillImages];
+    }
 }
 
+- (void)setUserInfo:(UserInfo *)userInfo
+{
+    _userInfo = userInfo;
+}
 
 - (void)fillImages{
     
@@ -81,15 +130,31 @@
         if(i >= _imgViewArr.count)
         {
             imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, _imgSize, _imgSize)];
+            [imgView setUserInteractionEnabled:YES];
+            [imgView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTouchImage:)]];
             [_scrollView addSubview:imgView];
+            
+            UIButton *deleteBtn = [[UIButton alloc] initWithFrame:CGRectMake((imgView.width-20)/2, 5, 20, 20)];
+            [deleteBtn setImage:[UIImage imageNamed:@"编辑照片--取消_03"] forState:UIControlStateNormal];
+            [deleteBtn addTarget:self action:@selector(onTouchDelete:) forControlEvents:UIControlEventTouchUpInside];
+            [imgView addSubview:deleteBtn];
+            [_imgViewArr addObject:imgView];
         }
         else
         {
             imgView = [_imgViewArr objectAtIndex:i];
         }
         
+        imgView.tag = i;
         [imgView setHidden:NO];
         
+        for(int j=0; j<imgView.subviews.count; j++)
+        {
+            UIView *subView = [imgView.subviews objectAtIndex:j];
+            subView.hidden = !_isEditing;
+            subView.tag = imgView.tag;
+        }
+        
         NSMutableDictionary *photo = [_photoArr objectAtIndex:i];
         NSString *thumb = [photo objectForKey:@"thumb"];
         NSURL *url = [NSURL URLWithString:thumb];
@@ -110,7 +175,8 @@
         _addImgView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, _imgSize, _imgSize)];
         _addImgView.backgroundColor = User.tinyGrayColor;
         [_addImgView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTouchAddImg:)]];
-        [_scrollView addSubview:_addImgView];
+        if(!_userInfo)
+            [_scrollView addSubview:_addImgView];
         
         UIImageView *addIcon = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, _imgSize/4, _imgSize/4)];
         addIcon.centerX = _imgSize / 2;
@@ -129,7 +195,7 @@
     float y = floorf(numPhotos/_imgColumns) * (_imgSize + _imgSpace);
     _addImgView.left = x;
     _addImgView.top = y;
-    
+    _addImgView.hidden = _isEditing;
     
     [_scrollView setContentSize:CGSizeMake(_scrollView.width, y+_imgSize)];
 }
@@ -151,17 +217,22 @@
 
 - (void)showImagePicker:(UIImagePickerControllerSourceType)type{
     
+    NSUInteger limit = 9 - _photoArr.count;
+    if(limit <= 0)
+    {
+        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:@"上传数量已达最多" delegate:nil cancelButtonTitle:@"确认" otherButtonTitles:nil, nil];
+        [alertView show];
+        return;
+    }
+    
     __weak typeof(self) weakSelf = self;
-    self.mediaFetcher.limit = 1;
+    self.mediaFetcher.limit = limit;
     [self.mediaFetcher fetchPhotoFromLibrary:^(NSArray *images, NSString *path, PHAssetMediaType type) {
         
         switch (type) {
             case PHAssetMediaTypeImage:
             {
-                for (UIImage *image in images) {
-                    [weakSelf uploadImage:image];
-                }
-
+                [weakSelf uploadImage:images index:0];
             }
                 break;
             case PHAssetMediaTypeVideo:
@@ -175,24 +246,86 @@
 }
 
 
-- (void)uploadImage:(UIImage *)image{
+- (void)uploadImage:(NSArray *)images index:(int)index{
+    
+    if(index >= images.count)
+    {
+        [self.view makeToast:@"全部上传完毕" duration:2 position:CSToastPositionBottom];
+        self.photoArr = [[User sharedInfo].userInfo.photeArr mutableCopy];
+        [self fillImages];
+        return;
+    }
     
     [SVProgressHUD show];
     
     __weak typeof(self) wself = self;
+    UIImage *image = [images objectAtIndex:index];
     [[HttpRequest shared] uploadPhoto:image success:^(NSMutableDictionary * _Nullable photoData) {
         
         [SVProgressHUD dismiss];
         
         [[User sharedInfo].userInfo.photeArr insertObject:photoData atIndex:0];
+        [wself uploadImage:images index:index+1];
+        
+    } failure:^{
+        [SVProgressHUD dismiss];
+        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:[NSString stringWithFormat:@"第%d张上传失败, 是否重新上传?", index+1] delegate:nil cancelButtonTitle:@"跳过" otherButtonTitles:@"确定", nil];
+        [alert showAlertWithCompletionHandler:^(NSInteger optIndex) {
+            if(optIndex == 1)
+                [wself uploadImage:images index:index];
+            else if(optIndex == 0)
+                [wself uploadImage:images index:index+1];
+        }];
+        
+        
+    }];
+    
+}
+
+
+- (void)onTouchImage:(UITapGestureRecognizer *)gestureRecognizer{
+    
+    UIView *viewClicked = [gestureRecognizer view];
+    
+    NSLog(@"show image %ld", (long)viewClicked.tag);
+    
+    int index = (int)viewClicked.tag;
+    ImagePagerViewController *imagePageVC = [[ImagePagerViewController alloc] init];
+    NSMutableDictionary *photo = [_photoArr objectAtIndex:index];
+    NSString *image = [photo objectForKey:@"pic"];
+    NSString *thumb = [photo objectForKey:@"thumb"];
+    [imagePageVC setImage:image thumb:thumb];
+    
+    [self.navigationController pushViewController:imagePageVC animated:YES];
+}
+
+
+- (void)onTouchDelete:(id)sender{
+    [SVProgressHUD show];
+    __weak typeof(self) wself = self;
+    UIButton *btn = sender;
+    NSMutableDictionary *photo = [_photoArr objectAtIndex:btn.tag];
+    NSString *imageId = [photo objectForKey:@"id"];
+    [[HttpRequest shared] deletePhoto:imageId success:^{
+        [SVProgressHUD dismiss];
+        
+        NSMutableArray *photoArr = [User sharedInfo].userInfo.photeArr;
+        for(int i=0; i<photoArr.count; i++)
+        {
+            NSString *pid = [[photoArr objectAtIndex:i] objectForKey:@"id"];
+            if([pid isEqualToString:imageId])
+            {
+                [photoArr removeObjectAtIndex:i];
+                break;
+            }
+        }
         _photoArr = [[User sharedInfo].userInfo.photeArr mutableCopy];
         [wself fillImages];
         
-        [self.view makeToast:@"上传成功" duration:2 position:CSToastPositionCenter];
     } failure:^{
-        [self.view makeToast:@"上传失败" duration:2 position:CSToastPositionCenter];
+        [SVProgressHUD dismiss];
+        [self.view makeToast:@"删除失败" duration:2 position:CSToastPositionCenter];
     }];
-    
 }
 
 

+ 10 - 2
NIMDemo/NIMDemo/SectionSetting/ChangePasswordViewController.m

@@ -10,6 +10,7 @@
 #import "HttpRequest.h"
 #import "SVProgressHUD.h"
 #import "UIView+Toast.h"
+#import "User.h"
 
 @interface ChangePasswordViewController ()<UITextFieldDelegate>
 
@@ -74,10 +75,9 @@
     NSString *change = _changeLabel.text;
     NSString *confirm = _confirmLabel.text;
     
-    int min = 8;
     int max = 12;
     
-    if(change.length < min || change.length > max)
+    if(change.length < Password_Min_Length || change.length > max)
     {
         UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"密码长度不正确" message:nil delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
         [alert show];
@@ -91,6 +91,14 @@
         return;
     }
     
+    if([change length] < Password_Min_Length)
+    {
+        NSString *title = [NSString stringWithFormat:@"密码长度至少需要%d个字符", Password_Min_Length];
+        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:nil delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
+        [alert show];
+        return;
+    }
+    
     [SVProgressHUD show];
     __weak typeof(self) wself = self;
     [[HttpRequest shared] changePassword:origin changePwd:change success:^{

+ 1 - 1
NIMDemo/NIMDemo/SectionSetting/SettingSecurityViewController.m

@@ -32,7 +32,7 @@
     [self.navigationItem setTitle:@"账号与安全"];
     
     User *user = [User sharedInfo];
-    _securityLabel.text = [NSString stringWithFormat:@"%d", user.userId];
+    _securityLabel.text = [User sharedInfo].userInfo.ssid;
     _mobileLabel.text = user.mobile;
 }
 

+ 4 - 2
NIMDemo/NIMDemo/SectionTrade/MyTradeTableViewCell.m

@@ -16,6 +16,7 @@
 #import "HttpRequest.h"
 #import "TradeDetailViewController.h"
 #import "TradeModifyViewController.h"
+#import "TradeUtil.h"
 
 @interface MyTradeTableViewCell() <UITextViewDelegate>
 
@@ -213,7 +214,8 @@
     _imgContainer.height = imgContainerHeight;
     _actionContainer.top = _imgContainer.bottom;
     
-    [_priorityBtn setTitle:[NSString stringWithFormat:@"置顶x%d", data.priority] forState:UIControlStateNormal];
+    NSString *local = [[TradeUtil shared] tradeLocal:data.priorityType];
+    [_priorityBtn setTitle:[NSString stringWithFormat:@"%@x%d", local, data.priority] forState:UIControlStateNormal];
     [_priorityBtn sizeToFit];
     _priorityBtn.width = _priorityBtn.width + 12;
     _priorityBtn.height = 24;
@@ -316,7 +318,7 @@
 }
 
 - (void)onTouchPrioirty:(id)sender{
-    
+
     if([[User sharedInfo] isMe:_data.userId])
     {
         [self onTouchModifyImage:nil];

+ 11 - 12
NIMDemo/NIMDemo/SectionTrade/MyTradeViewController.m

@@ -203,33 +203,31 @@
     else if(sort == TradeSortMyFollowed)
         page = _followPage = MAX(1, _followPage);
     
+    __weak typeof(self) wself = self;
     [[HttpRequest shared] tradeList:sort page:page success:^(NSMutableArray * _Nullable dataList) {
         
         if(sort == TradeSortMyPublished)
         {
-            if(!self.publishDataList)
-                self.publishDataList = dataList;
+            if(!wself.publishDataList)
+                wself.publishDataList = dataList;
             else
-                [self.publishDataList addObjectsFromArray:dataList];
-            
-            [self.tableView reloadData];
+                [wself.publishDataList addObjectsFromArray:dataList];
             
             if(dataList.count > 0)
                 _publishPage++;
         }
         else if(sort == TradeSortMyFollowed)
         {
-            if(!self.followDataList)
-                self.followDataList = dataList;
+            if(!wself.followDataList)
+                wself.followDataList = dataList;
             else
-                [self.followDataList addObjectsFromArray:dataList];
-            
-            [self.tableView reloadData];
+                [wself.followDataList addObjectsFromArray:dataList];
             
             if(dataList.count > 0)
                 _followPage++;
         }
-
+        [wself.tableView reloadData];
+        
         _isFetching = NO;
     } failure:^{
         _isFetching = NO;
@@ -289,7 +287,8 @@
     if([dataObj isKindOfClass:[TradeData class]])
     {
         TradeData *tradeData = (TradeData *)dataObj;
-        return tradeData.cellHeight;
+        if(tradeData.cellHeight > 0)
+            return tradeData.cellHeight;
     }
     
     return 30;

+ 1 - 0
NIMDemo/NIMDemo/SectionTrade/TradeData.h

@@ -37,6 +37,7 @@ typedef NS_ENUM(NSInteger, TradeSort) {
 @property (nonatomic, strong) NSMutableArray        *picIdArr;
 @property (nonatomic, assign) int                   priorityType;
 @property (nonatomic, assign) int                   priority;
+@property (nonatomic, assign) float                 price;
 @property (nonatomic, strong) NSString              *time;
 @property (nonatomic, assign) BOOL                  followed;
 @property (nonatomic, assign) int                   followCount;

+ 1 - 0
NIMDemo/NIMDemo/SectionTrade/TradeData.m

@@ -23,6 +23,7 @@
     
     _priorityType = [[data objectForKey:@"priority_type"] intValue];
     _priority = [[data objectForKey:@"priority"] intValue];
+    _price = [[data objectForKey:@"price"] floatValue];
     _time = [data objectForKey:@"inputtime"];
     
     _followed = [[data objectForKey:@"follow"] intValue] > 0 ? YES : NO;

+ 1 - 0
NIMDemo/NIMDemo/SectionTrade/TradeDetailViewController.h

@@ -12,5 +12,6 @@
 @interface TradeDetailViewController : UIViewController
 
 - (instancetype)initWithTradeData:(TradeData *)tradeData;
+- (instancetype)initWithTradeId:(NSString *)tradeId;
 
 @end

+ 101 - 21
NIMDemo/NIMDemo/SectionTrade/TradeDetailViewController.m

@@ -14,8 +14,15 @@
 #import "NIMKit.h"
 #import "TradeUtil.h"
 #import "UIImageView+WebCache.h"
+#import "User.h"
+#import "WhosayActivity.h"
+#import "NIMContactSelectViewController.h"
+#import "NTESShareAttachment.h"
+#import "NTESSessionMsgConverter.h"
+#import "UIView+Toast.h"
+#import "HttpRequest.h"
 
-@interface TradeDetailViewController ()<UITextViewDelegate>
+@interface TradeDetailViewController ()<UITextViewDelegate, NIMContactSelectDelegate>
 
 @property (nonatomic, strong) TradeData                     *data;
 
@@ -44,6 +51,26 @@
     
 }
 
+- (instancetype)initWithTradeId:(NSString *)tradeId
+{
+    self = [super init];
+    if(self)
+    {
+        [self fetchData:tradeId];
+    }
+    return self;
+}
+
+- (void)fetchData:(NSString *)tradeId{
+    __weak typeof(self) wself = self;
+    [[HttpRequest shared] tradeInfo:tradeId success:^(TradeData * _Nullable data) {
+        wself.data = data;
+        [wself updateContent];
+    } failure:^{
+        
+    }];
+}
+
 - (void)viewDidLoad {
     [super viewDidLoad];
     [self setUpComponent];
@@ -132,6 +159,9 @@
 
 - (void)updateContent{
     
+    if(!_data)
+        return;
+    
     NIMUser *user = [[[NIMSDK sharedSDK] userManager] userInfo:_data.userId];
     NSURL *avatarURL = user && user.userInfo.thumbAvatarUrl ? [NSURL URLWithString:user.userInfo.thumbAvatarUrl] : nil;
     [_avatarView nim_setImageWithURL:avatarURL placeholderImage:User.defaultUserAvatar];
@@ -140,7 +170,8 @@
     _localLabel.text = _data.district;
     
     _timeLabel.text = _data.time;
-    [_priorityBtn setTitle:[NSString stringWithFormat:@"置顶%d", _data.priority] forState:UIControlStateNormal];
+    NSString *local = [[TradeUtil shared] tradeLocal:_data.priorityType];
+    [_priorityBtn setTitle:[NSString stringWithFormat:@"%@x%d", local, _data.priority] forState:UIControlStateNormal];
     
     _msgTextView.attributedText = [[TradeUtil shared] tradeMsg:_data.msg tradeType:_data.type tradePriorityType:_data.priorityType];
     [_msgTextView sizeToFit];
@@ -151,16 +182,13 @@
 - (void)updateImages{
     
     _imgContainer.top = _msgTextView.bottom + 5;
-    
-    float imgWidth = _imgContainer.width;
-    
     _firstImg = nil;
     
     __weak typeof(self) wself = self;
     for(int i=0; i<_data.picArr.count; i++)
     {
         NSURL *url = [NSURL URLWithString:[_data.picArr objectAtIndex:i]];
-        UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, _imgContainer.width, 0)];
+        UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 60 * i, 60, 60)];
         [imgView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTouchImage:)]];
         [imgView setContentScaleFactor:[[UIScreen mainScreen] scale]];
         imgView.contentMode =  UIViewContentModeScaleToFill;
@@ -168,18 +196,7 @@
         imgView.tag = i;
         
         NSLog(@"load image url %@", url.absoluteString);
-        [imgView sd_setImageWithURL:url placeholderImage:nil options:0 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
-            
-            CGSize size = image.size;
-            
-            float width = size.width;
-            float height = size.height;
-            float s = imgWidth / size.width;
-            width = width * s;
-            height = height * s;
-            imgView.width = width;
-            imgView.height = height;
-            
+        [imgView sd_setImageWithURL:url placeholderImage:User.defaultPlaceHolderImage options:0 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
             [wself updateImageLayout];
         }];
         
@@ -192,12 +209,26 @@
     
     float startY = 0;
     float space = 10;
+    float imgWidth = _imgContainer.width;
     
     for(int i=0; i<_imgContainer.subviews.count; i++)
     {
         UIImageView *imgView = [_imgContainer.subviews objectAtIndex:i];
         NSLog(@"image view width %f height %f", imgView.width, imgView.height);
         
+        UIImage *image = imgView.image;
+        if(image)
+        {
+            CGSize size = image.size;
+            
+            float width = size.width;
+            float height = size.height;
+            float s = imgWidth / size.width;
+            width = width * s;
+            height = height * s;
+            imgView.width = width;
+            imgView.height = height;
+        }
         if(i==0 && imgView.height > 0 && !_firstImg)
         {
             _firstImg = imgView.image;
@@ -243,7 +274,8 @@
 
 - (void)onTouchShare:(id)sender{
     
-    NSString *textToShare = _data.msg;
+    NSString *name = [[User sharedInfo] getUserNameById:[NIMSDK sharedSDK].loginManager.currentAccount];
+    NSString *textToShare = [NSString stringWithFormat:@"%@ --来自%@的谁说快讯广告", _msgTextView.text, name];
     
     NSArray *activityItems = nil;
     if(_firstImg)
@@ -255,8 +287,56 @@
         activityItems = @[textToShare];
     }
     
-    UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:nil];
-    activityVC.excludedActivityTypes = @[UIActivityTypePostToVimeo];
+    UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:@[self.whosayActivity]];
+    activityVC.excludedActivityTypes = @[];
     [self presentViewController:activityVC animated:YES completion:nil];
 }
+
+
+- (WhosayActivity *)whosayActivity
+{
+    WhosayActivity *whosayActivity = [[WhosayActivity alloc] init];
+    __weak typeof(self) wself = self;
+    [whosayActivity setWhosayBlock:^{
+        [wself presentMemberSelector];
+    }];
+    
+    return whosayActivity;
+}
+
+- (void)presentMemberSelector{
+    NSMutableArray *users = [[NSMutableArray alloc] init];
+    NSString *currentUserID = [[[NIMSDK sharedSDK] loginManager] currentAccount];
+    [users addObject:currentUserID];
+    
+    NIMContactFollowSelectConfig *config = [[NIMContactFollowSelectConfig alloc] init];
+    config.filterIds = users;
+    config.needMutiSelected = NO;
+    NIMContactSelectViewController *vc = [[NIMContactSelectViewController alloc] initWithConfig:config];
+    vc.delegate = self;
+    [vc show];
+}
+
+- (void)didFinishedSelect:(NSArray *)selectedContacts{
+    if (!selectedContacts.count) {
+        return;
+    }
+    
+    NSString *name = [[User sharedInfo] getUserNameById:[NIMSDK sharedSDK].loginManager.currentAccount];
+    NSString *textToShare = [NSString stringWithFormat:@"%@ --来自%@的谁说快讯广告", _msgTextView.text, name];
+    
+    NSString *userId = [selectedContacts firstObject];
+    NSString *thumbToShare = _data.thumbArr.count ? [_data.thumbArr firstObject] : @"";
+    
+    NTESShareAttachment *attachment = [[NTESShareAttachment alloc] init];
+    attachment.tradeId = _data.tradeId;
+    attachment.info = textToShare;
+    attachment.thumb = thumbToShare;
+    
+    NIMMessage *message = [NTESSessionMsgConverter msgWithShare:attachment];
+    NIMSession *session = [NIMSession session:userId type:NIMSessionTypeP2P];
+    [[[NIMSDK sharedSDK] chatManager] sendMessage:message toSession:session error:nil];
+    
+    [self.view makeToast:@"分享成功" duration:2.0 position:CSToastPositionCenter];
+}
 @end

+ 25 - 12
NIMDemo/NIMDemo/SectionTrade/TradeModifyViewController.m

@@ -28,7 +28,7 @@
 @property (nonatomic, strong) UIView                *addImgView;
 @property (nonatomic, strong) NIMKitMediaFetcher    *mediaFetcher;
 
-
+@property (nonatomic, strong) UILabel               *titleLabel;
 @property (nonatomic, strong) UILabel               *countLabel;
 @property (nonatomic, strong) UIButton              *countBtn;
 @property (nonatomic, strong) UISlider              *slider;
@@ -66,7 +66,6 @@
         }
     }
     return self;
-    
 }
 
 - (void)viewDidLoad {
@@ -144,11 +143,11 @@
     
     
     
-    UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, _imgSize * 3 + 40, 100, 40)];
-    titleLabel.text = @"添加置顶";
-    [_scrollView addSubview:titleLabel];
+    _titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, _imgSize * 3 + 40, width-20, 40)];
+    _titleLabel.text = @"添加置顶";
+    [_scrollView addSubview:_titleLabel];
     
-    _countLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, titleLabel.top, width-20, 40)];
+    _countLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, _titleLabel.top, width-20, 40)];
     _countLabel.textAlignment = NSTextAlignmentRight;
     [_scrollView addSubview:_countLabel];
     
@@ -161,11 +160,11 @@
     UILabel *tipLabel = [[UILabel alloc] initWithFrame:CGRectMake(50, _countLabel.bottom-10, self.view.width-50-10, 20)];
     tipLabel.textColor = UIColor.redColor;
     tipLabel.font = [UIFont systemFontOfSize:12];
-    tipLabel.text = @"一天可发布三条,道具数量决定便民贴排名";
+    tipLabel.text = @"一天可发布三条";
     tipLabel.textAlignment = NSTextAlignmentRight;
-    [_scrollView addSubview:tipLabel];
+    //[_scrollView addSubview:tipLabel];
     
-    _slider = [[UISlider alloc] initWithFrame:CGRectMake(50, titleLabel.bottom, _scrollView.width-70, 40)];
+    _slider = [[UISlider alloc] initWithFrame:CGRectMake(50, _titleLabel.bottom, _scrollView.width-70, 40)];
     _slider.minimumValue = 0;
     _slider.maximumValue = 100;
     _slider.value = 0;
@@ -177,8 +176,6 @@
     
 }
 
-
-
 - (void)reloadData{
     
     while(_imgArr.count > 0)
@@ -383,10 +380,26 @@
 
 
 - (void)sliderValueChanged{
-    _countLabel.text = [NSString stringWithFormat:@"x%d(+%.0f) (%@ 单价%d)", _data.priority, roundf(_slider.value), _priorityTypeItem.name, _priorityTypeItem.price];
+//    _countLabel.text = [NSString stringWithFormat:@"x%d(+%.0f) (%@ 单价%d)", _data.priority, roundf(_slider.value), _priorityTypeItem.name, _priorityTypeItem.price];
+    [self updatePriorityTip:_slider.value];
 }
 
+- (void)updatePriorityTip:(int)count{
+    float totalPrice = _priorityTypeItem.price * count;
+    _titleLabel.text = [NSString stringWithFormat:@"置顶x%d(+%.0f)  共%@说币", _data.priority, roundf(_slider.value), [self formatFloat:totalPrice]];
+    _countLabel.text = _priorityTypeItem.name;
+}
 
+- (NSString *)formatFloat:(float)f
+{
+    if (fmodf(f, 1)==0) {//如果有一位小数点
+        return [NSString stringWithFormat:@"%.0f",f];
+    } else if (fmodf(f*10, 1)==0) {//如果有两位小数点
+        return [NSString stringWithFormat:@"%.1f",f];
+    } else {
+        return [NSString stringWithFormat:@"%.2f",f];
+    }
+}
 
 - (void)tradeEdit:(id)sender{
     

+ 28 - 3
NIMDemo/NIMDemo/SectionTrade/TradePublishManager.m

@@ -63,7 +63,32 @@
     
     
     [SVProgressHUD show];
-    [self uploadPicture];
+    __weak typeof(self) wself = self;
+    [[User sharedInfo] fetchTodyTradePublishCount:^(int count) {
+        
+        if(count >= Trade_Max_Publish_Count)
+        {
+            NSString *msg = [NSString stringWithFormat:@"一天只可发布%d条", Trade_Max_Publish_Count];
+            UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:msg message:nil delegate:nil cancelButtonTitle:@"确认" otherButtonTitles:nil];
+            [alertView show];
+            
+            [SVProgressHUD dismiss];
+            if ([_delegate respondsToSelector:@selector(tradePublishResult:)]){
+                [_delegate tradePublishResult:NO];
+                _delegate = nil;
+            }
+            return;
+        }
+        
+        [wself uploadPicture];
+    } failure:^{
+        [SVProgressHUD dismiss];
+        if ([_delegate respondsToSelector:@selector(tradePublishResult:)]){
+            [_delegate tradePublishResult:NO];
+            _delegate = nil;
+        }
+    }];
+    
 }
 
 - (void)uploadPicture{
@@ -109,7 +134,7 @@
     NSString *userId = [NSString stringWithFormat:@"%d", [User sharedInfo].userId];
     NSDictionary *dict = @{@"user_id":userId};
     
-    NSString *urlString = @"http://whosay.dashgame.com/index.php?m=who&c=trade&a=upload";
+    NSString *urlString = [NSString stringWithFormat:@"%@%@", [HttpRequest shared].urlRoot, @"index.php?m=who&c=trade&a=upload"];
     
     AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
     manager.responseSerializer = [AFJSONResponseSerializer serializer];
@@ -117,7 +142,7 @@
     
     [manager POST:urlString parameters:dict constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
         
-        NSData *data = UIImageJPEGRepresentation(image, 1);
+        NSData *data = UIImageJPEGRepresentation(image, Image_Compression_Quality);
         [formData appendPartWithFileData:data name:@"upload" fileName:[NSString stringWithFormat:@"image_%d.jpg", _uploadIndex] mimeType:@"image/jpg"];
         
     } progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {

+ 5 - 3
NIMDemo/NIMDemo/SectionTrade/TradeTableViewCell.m

@@ -158,6 +158,9 @@ return self;
     int i=0;
     for(i=0; i<data.thumbArr.count; i++)
     {
+        if(i >= 3)
+            break;
+        
         float startX = (i % 3) * (imgSize + imgPadding);
         float startY = (i / 3) * (imgSize + imgPadding);
         imgContainerHeight = startY + imgSize;
@@ -182,8 +185,6 @@ return self;
         NSURL *url = [NSURL URLWithString:path];
         [img sd_setImageWithURL:url placeholderImage:[UIImage imageNamed:@"聊天-_17"]];
         [img setTag:i];
-        
-        
     }
     
     for(int j=i; j<_imgContainer.subviews.count; j++)
@@ -194,7 +195,8 @@ return self;
     _imgContainer.height = imgContainerHeight;
     
     _actionContainer.top = _imgContainer.bottom;
-    [_priorityBtn setTitle:[NSString stringWithFormat:@"置顶x%d", data.priority] forState:UIControlStateNormal];
+    NSString *local = [[TradeUtil shared] tradeLocal:data.priorityType];
+    [_priorityBtn setTitle:[NSString stringWithFormat:@"%@x%d", local, data.priority] forState:UIControlStateNormal];
     [_priorityBtn sizeToFit];
     _priorityBtn.width = _priorityBtn.width + 12;
     _priorityBtn.height = 24;

+ 1 - 0
NIMDemo/NIMDemo/SectionTrade/TradeUtil.h

@@ -13,5 +13,6 @@
 
 + (instancetype)shared;
 - (NSMutableAttributedString *)tradeMsg:(NSString *)msg tradeType:(int)tradeType tradePriorityType:(int)tradePriorityType;
+- (NSString *)tradeLocal:(int)tradePriorityType;
 
 @end

+ 25 - 5
NIMDemo/NIMDemo/SectionTrade/TradeUtil.m

@@ -34,22 +34,22 @@
     if(tradePriorityType == TradePriorityCountry)
     {
         priorityColor = User.greenColor;
-        priorityText = @"[国]";
+        priorityText = @"[国]";
     }
     else if(tradePriorityType == TradePriorityProvince)
     {
         priorityColor = User.orangeColor;
-        priorityText = @"[省]";
+        priorityText = @"[省]";
     }
     else if(tradePriorityType == TradePriorityCity)
     {
         priorityColor = User.orangeColor;
-        priorityText = @"[市]";
+        priorityText = @"[市]";
     }
     else if(tradePriorityType == TradePriorityDistrict)
     {
         priorityColor = User.orangeColor;
-        priorityText = @"[区县]";
+        priorityText = @"[本地]";
     }
     else
     {
@@ -60,7 +60,7 @@
                            [UIFont systemFontOfSize:15.0], NSFontAttributeName,
                            priorityColor, NSForegroundColorAttributeName, nil];
     NSMutableAttributedString *appendString = [[NSMutableAttributedString alloc] initWithString:priorityText attributes:attrs];
-    [attrString appendAttributedString:appendString];
+    //[attrString appendAttributedString:appendString];
     
     
     
@@ -99,6 +99,26 @@
     return attrString;
 }
 
+- (NSString *)tradeLocal:(int)tradePriorityType
+{
+    if(tradePriorityType == TradePriorityCountry)
+    {
+        return @"全国";
+    }
+    else if(tradePriorityType == TradePriorityProvince)
+    {
+        return @"全省";
+    }
+    else if(tradePriorityType == TradePriorityCity)
+    {
+        return @"全市";
+    }
+    else if(tradePriorityType == TradePriorityDistrict)
+    {
+        return @"本地";
+    }
 
+    return @"";
+}
 
 @end

+ 37 - 13
NIMDemo/NIMDemo/SectionTrade/TradeViewController.m

@@ -18,6 +18,7 @@
 #import "UIView+Toast.h"
 #import "TradeTopBarItem.h"
 #import "SVProgressHUD.h"
+#import "TradeDetailViewController.h"
 
 
 @interface TradeViewController () <
@@ -67,7 +68,8 @@ float postHeight = 30;
     [self tableView];
     
     UIButton *showInputBtn = [UIButton buttonWithType:UIButtonTypeCustom];
-    showInputBtn.frame = CGRectMake(self.view.width - 65, self.view.height-115, 40, 40);
+    float btnSize = 60;
+    showInputBtn.frame = CGRectMake(self.view.width - btnSize - 25, self.view.height - btnSize - 75, btnSize, btnSize);
     [showInputBtn setImage:[UIImage imageNamed:@"发布交易贴"] forState:UIControlStateNormal];
     [showInputBtn addTarget:self action:@selector(showTradeInput:) forControlEvents:UIControlEventTouchUpInside];
     [self.view addSubview:showInputBtn];
@@ -172,7 +174,7 @@ float postHeight = 30;
     _tradeItem2.hidden = YES;
     [self.view addSubview:_tradeItem2];
     
-    _timer = [NSTimer scheduledTimerWithTimeInterval:8.0 target:self selector:@selector(requestLastTradeDataList) userInfo:nil repeats:YES];
+//    _timer = [NSTimer scheduledTimerWithTimeInterval:8.0 target:self selector:@selector(requestLastTradeDataList) userInfo:nil repeats:YES];
     
     
     
@@ -189,19 +191,24 @@ float postHeight = 30;
     
     [self.view addSubview:_searchController.searchBar];
     
+    
+    [[User sharedInfo] requestFollowList:^{
+        
+    }];
+    
 }
 
 - (void)didReceiveMemoryWarning {
     [super didReceiveMemoryWarning];
     // Dispose of any resources that can be recreated.
     
-    [_timer invalidate];
+    //[_timer invalidate];
 }
 
 - (void)viewWillAppear:(BOOL)animated{
     [super viewWillAppear:animated];
     
-    [_timer setFireDate:[NSDate distantPast]];
+    //[_timer setFireDate:[NSDate distantPast]];
     
     User *user = [User sharedInfo];
     
@@ -216,16 +223,13 @@ float postHeight = 30;
     
     UINavigationItem *navItem = self.parentViewController.navigationItem;
     
-    navItem.title = @"便民贴";
+    navItem.title = @"快讯广告";
     
     
     NSString *title = @"请重试定位";
     if(![user.district isEqualToString:@""])
     {
-        if([user.city isEqualToString:user.district])
-            title = user.city;
-        else
-            title = [NSString stringWithFormat:@"%@%@", user.city, user.district];
+        title = user.district;
         
         if(title.length > 6)
         {
@@ -272,11 +276,13 @@ float postHeight = 30;
     
     
     
-    _balanceLabel.text = [NSString stringWithFormat:@"余额:%d", [User sharedInfo].coin];
+    _balanceLabel.text = [NSString stringWithFormat:@"余额:%@", [[User sharedInfo] getCoinStr]];
     
     [self.tableView reloadData];
     
     _searchController.searchBar.hidden = YES;
+    
+    [_tradeInput fillItemData:[User sharedInfo].tradePriorityItemArr];
 }
 
 - (void)viewDidAppear:(BOOL)animated{
@@ -287,7 +293,8 @@ float postHeight = 30;
 
 - (void)viewWillDisappear:(BOOL)animated{
     [super viewWillDisappear:animated];
-    [_timer setFireDate:[NSDate distantFuture]];
+    //[_timer setFireDate:[NSDate distantFuture]];
+    [_searchController setActive:NO];
 }
 
 
@@ -399,8 +406,9 @@ float postHeight = 30;
     
     _page = MAX(1, _page);
     
-    
+    [SVProgressHUD show];
     [[HttpRequest shared] tradeList:_tradeSort page:_page success:^(NSMutableArray * _Nullable dataList) {
+        [SVProgressHUD dismiss];
         if(!self.dataList)
             self.dataList = dataList;
         else
@@ -413,6 +421,7 @@ float postHeight = 30;
         
         _isFetching = NO;
     } failure:^{
+        [SVProgressHUD dismiss];
         _isFetching = NO;
     }];
 }
@@ -427,9 +436,10 @@ float postHeight = 30;
     
     _page = MAX(1, _page);
     
-    
+    [SVProgressHUD show];
     __weak typeof(self) wself = self;
     [[HttpRequest shared] tradeSearchList:_searchKey tradeSort:_tradeSort page:_page success:^(NSMutableArray * _Nullable dataList) {
+        [SVProgressHUD dismiss];
         if(!wself.searchList)
             wself.searchList = dataList;
         else
@@ -444,6 +454,7 @@ float postHeight = 30;
         
         [SVProgressHUD dismiss];
     } failure:^{
+        [SVProgressHUD dismiss];
         wself.isFetching = NO;
     }];
 }
@@ -623,6 +634,9 @@ float postHeight = 30;
         [self reset];
         [self fetchDataList];
         [self.view makeToast:@"发布成功" duration:2 position:CSToastPositionCenter];
+        _balanceLabel.text = [NSString stringWithFormat:@"余额:%@", [[User sharedInfo] getCoinStr]];
+        
+        [self showPublishedTrade];
     }
     else
     {
@@ -630,6 +644,16 @@ float postHeight = 30;
     }
 }
 
+- (void)showPublishedTrade{
+    if([User sharedInfo].tradePublishLastId > 0)
+    {
+        NSString *tradeId = [NSString stringWithFormat:@"%d", [User sharedInfo].tradePublishLastId];
+        TradeDetailViewController *detailVC = [[TradeDetailViewController alloc] initWithTradeId:tradeId];
+        [self.navigationController pushViewController:detailVC animated:YES];
+        [User sharedInfo].tradePublishLastId = 0;
+    }
+}
+
 
 
 - (void)requestLastTradeDataList{

+ 15 - 0
NIMDemo/NIMDemo/SectionTrade/WhosayActivity.h

@@ -0,0 +1,15 @@
+//
+//  WhosayActivity.h
+//  NIMDemo
+//
+//  Created by Fenix Wang on 2017/8/9.
+//  Copyright © 2017年 Netease. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface WhosayActivity : UIActivity
+
+@property (nonatomic, copy) void(^whosayBlock)(void);
+
+@end

+ 67 - 0
NIMDemo/NIMDemo/SectionTrade/WhosayActivity.m

@@ -0,0 +1,67 @@
+//
+//  WhosayActivity.m
+//  NIMDemo
+//
+//  Created by Fenix Wang on 2017/8/9.
+//  Copyright © 2017年 Netease. All rights reserved.
+//
+
+#import "WhosayActivity.h"
+#import "User.h"
+
+@interface WhosayActivity()
+
+@property (nonatomic, strong) UIImage           *image;
+@property (nonatomic, strong) NSString          *text;
+
+@end
+
+@implementation WhosayActivity
+
+- (NSString *)activityType {
+    
+    return @"WhosayActivity";
+}
+
+- (NSString *)activityTitle {
+    
+    return @"谁说";
+}
+
+- (UIImage *)_activityImage {
+    
+    return [UIImage imageNamed:@"交易帖详情---更多_03"];
+}
+
+- (void)performActivity {
+    [self activityDidFinish:YES];
+    
+    if(_whosayBlock)
+        _whosayBlock();
+}
+
+- (BOOL)canPerformWithActivityItems:(NSArray *)activityItems {
+    
+    if (activityItems.count > 0) {
+        
+        return YES;
+    }
+    
+    return NO;
+}
+
+- (void)prepareWithActivityItems:(NSArray *)activityItems{
+    for(int i=0; i<activityItems.count; i++)
+    {
+        id item = [activityItems objectAtIndex:i];
+        if([item isKindOfClass:[NSString class]])
+        {
+            _text = item;
+        }
+        else if([item isKindOfClass:[UIImage class]])
+        {
+            _image = item;
+        }
+    }
+}
+@end

+ 12 - 0
NIMDemo/NIMDemo/SettingAccountViewController.m

@@ -14,6 +14,7 @@
 #import "UIActionSheet+NTESBlock.h"
 #import "UIView+Toast.h"
 
+
 @interface SettingAccountViewController ()
 
 @property (weak, nonatomic) IBOutlet UILabel *securityLabel;
@@ -43,6 +44,7 @@
     [self.navigationItem setTitle:@"设置"];
     
     [self updateNotify];
+    [self updateSecurity];
 }
 
 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
@@ -130,6 +132,16 @@
     }
 }
 
+- (void)updateSecurity{
+    int security = [User sharedInfo].security;
+    if(security == 2)
+        _securityLabel.text = @"安全等级高";
+    else if(security == 1)
+        _securityLabel.text = @"安全等级中等";
+    else
+        _securityLabel.text = @"安全等级低";
+}
+
 - (void)handlePrivacy{
     UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
     UIViewController *vc = [storyBoard instantiateViewControllerWithIdentifier:@"Privacy"];

+ 46 - 25
NIMDemo/NIMDemo/SettingTableViewController.m

@@ -16,10 +16,14 @@
 #import "AppDelegate.h"
 #import "SettingOptionTableViewCell.h"
 #import "NTESUserInfoSettingViewController.h"
+#import "HttpRequest.h"
+#import "UIView+Toast.h"
+
 
 @interface SettingTableViewController ()
 
 @property (nonatomic, strong) NSMutableArray                *dataArr;
+@property (nonatomic, strong) NSMutableArray                *socialList;
 
 @end
 
@@ -28,29 +32,7 @@
 - (void)viewDidLoad {
     [super viewDidLoad];
     
-    _dataArr = [[NSMutableArray alloc] init];
-    
-    float topHeight = 300;
-    float photoHeight = [User sharedInfo].userInfo.photeArr.count > 4 ? self.view.width / 4 * 2 : self.view.width / 4;
-    topHeight += photoHeight;
-    
-    [_dataArr addObject:@{@"cellId":@"top",
-                          @"height":[@(topHeight) stringValue]}];
-    
-    [_dataArr addObject:@{@"cellId":@"option",
-                          @"type":@"near",
-                          @"height":@"44"}];
-    
-    [_dataArr addObject:@{@"cellId":@"option",
-                          @"type":@"trade",
-                          @"height":@"44"}];
-    
-    [_dataArr addObject:@{@"cellId":@"option",
-                          @"type":@"setting",
-                          @"height":@"44"}];
-    
-    
-    
+    [self fillData];
     self.tableView.contentInset = UIEdgeInsetsMake(-69, 0, 0, 0);
 }
 
@@ -80,8 +62,6 @@
     UIBarButtonItem *addItem = [[UIBarButtonItem alloc] initWithCustomView:addBtn];
     
     [navItem setRightBarButtonItems:@[addItem]];
-    
-    [self.tableView reloadData];
 }
 
 - (void)viewDidAppear:(BOOL)animated{
@@ -89,6 +69,11 @@
     
     AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
     [appDelegate transparentNavBar:self.parentViewController];
+    
+    [self fillData];
+    [self.tableView reloadData];
+    
+    [self fetchSocial];
 }
 
 - (void)viewWillDisappear:(BOOL)animated{
@@ -97,6 +82,40 @@
     [appDelegate orangeNavBar:self.parentViewController];
 }
 
+- (void)fillData{
+    _dataArr = [[NSMutableArray alloc] init];
+    
+    float topHeight = 340;
+    float photoHeight = [User sharedInfo].userInfo.photeArr.count >= 4 ? self.view.width / 4 * 2 : self.view.width / 4;
+    float socialHeight = 130;
+    topHeight += photoHeight + socialHeight;
+    
+    [_dataArr addObject:@{@"cellId":@"top",
+                          @"height":[@(topHeight) stringValue]}];
+    
+    [_dataArr addObject:@{@"cellId":@"option",
+                          @"type":@"near",
+                          @"height":@"44"}];
+    
+    [_dataArr addObject:@{@"cellId":@"option",
+                          @"type":@"trade",
+                          @"height":@"44"}];
+    
+    [_dataArr addObject:@{@"cellId":@"option",
+                          @"type":@"setting",
+                          @"height":@"44"}];
+}
+
+- (void)fetchSocial{
+    __weak typeof(self) wself = self;
+    [[HttpRequest shared] getSocialDataList:nil targetId:[NIMSDK sharedSDK].loginManager.currentAccount success:^(NSMutableArray * _Nullable dataList) {
+        wself.socialList = dataList;
+        [wself.tableView reloadData];
+    } failure:^{
+        [self.view makeToast:@"获取动态失败"];
+    }];
+}
+
 #pragma mark - Table view data source
 
 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
@@ -126,6 +145,7 @@
             [cell initSize:self.view.width cellHeight:[[dataObj objectForKey:@"height"] floatValue]];
         }
         [cell fillPhotos];
+        [cell fillSocial:self.socialList];
         baseCell = cell;
     }
     else if([cellId isEqualToString:@"option"])
@@ -162,4 +182,5 @@
 
 
 
+
 @end

+ 1 - 0
NIMDemo/NIMDemo/SettingTopTableViewCell.h

@@ -12,5 +12,6 @@
 
 - (void)initSize:(CGFloat)cellWidth cellHeight:(CGFloat)cellHeight;
 - (void)fillPhotos;
+- (void)fillSocial:(NSMutableArray *)list;
 
 @end

+ 192 - 25
NIMDemo/NIMDemo/SettingTopTableViewCell.m

@@ -15,6 +15,9 @@
 #import "UIActionSheet+NTESBlock.h"
 #import "HttpRequest.h"
 #import "AddPhotoViewController.h"
+#import "SVProgressHUD.h"
+#import "ImagePagerViewController.h"
+#import "SocialTableViewController.h"
 
 @interface SettingTopTableViewCell()<UINavigationControllerDelegate, UIImagePickerControllerDelegate>
 
@@ -25,9 +28,21 @@
 @property (strong, nonatomic) UILabel                 *userIdLabel;
 @property (strong, nonatomic) UIView                  *photoContainer;
 @property (strong, nonatomic) UIButton                *photoAddBtn;
+@property (strong, nonatomic) UIView                  *step;
 
 @property (nonatomic, assign) float                   cellWidth;
 
+@property (nonatomic, strong) NSMutableArray          *picArr;
+@property (nonatomic, strong) NSMutableArray          *thumbArr;
+
+@property (nonatomic, strong) NSMutableArray          *socialPicArr;
+@property (nonatomic, strong) NSMutableArray          *socialThumbArr;
+
+@property (nonatomic, strong) UILabel                 *socialLabel;
+@property (nonatomic, strong) UIView                  *socialContainer;
+@property (nonatomic, strong) UIView                  *socialPicContainer;
+
+
 @end
 
 @implementation SettingTopTableViewCell
@@ -45,16 +60,29 @@
     
     self.cellWidth = cellWidth;
     
-    NSString *userId = [NIMSDK sharedSDK].loginManager.currentAccount;
-    NIMUser *nimUser = [[NIMSDK sharedSDK].userManager userInfo:userId];
+    _picArr = [[NSMutableArray alloc] init];
+    _thumbArr = [[NSMutableArray alloc] init];
+    
+    _socialPicArr = [[NSMutableArray alloc] init];
+    _socialThumbArr = [[NSMutableArray alloc] init];
     
-    _topImgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, cellWidth, 180)];
+    _topImgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, cellWidth, 240)];
     _topImgView.userInteractionEnabled = YES;
     _topImgView.contentMode =  UIViewContentModeScaleAspectFill;
     _topImgView.clipsToBounds  = YES;
     [_topImgView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTouchTopImage:)]];
     [self addSubview:_topImgView];
     
+    UILabel *topImgLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, cellWidth, 20)];
+    topImgLabel.text = @"轻触换背景";
+    topImgLabel.centerY = _topImgView.centerY;
+    topImgLabel.font = [UIFont systemFontOfSize:15];
+    topImgLabel.textColor = UIColor.whiteColor;
+    topImgLabel.shadowColor = UIColor.grayColor;
+    topImgLabel.shadowOffset = CGSizeMake(1, 1);
+    topImgLabel.textAlignment = NSTextAlignmentCenter;
+    [self addSubview:topImgLabel];
+    
     _avatarImg = [[NIMAvatarImageView alloc] initWithFrame:CGRectMake(0, 0, 80, 80)];
     _avatarImg.centerX = cellWidth / 2;
     _avatarImg.centerY = _topImgView.bottom;
@@ -64,65 +92,92 @@
     [self addSubview:_avatarImg];
     
     _genderImg = [[UIImageView alloc] initWithFrame:CGRectMake(_avatarImg.right-20, _avatarImg.bottom-20, 20, 20)];
-    if(nimUser.userInfo.gender == NIMUserGenderMale || nimUser.userInfo.gender == NIMUserGenderUnknown)
-    {
-        [_genderImg setImage:[UIImage imageNamed:@"我的_07 (3)"]];
-    }
-    else if(nimUser.userInfo.gender == NIMUserGenderFemale)
-    {
-        [_genderImg setImage:[UIImage imageNamed:@"我的_07 (4)"]];
-    }
     [self addSubview:_genderImg];
     
     _userNameLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, _avatarImg.bottom + 10, cellWidth, 20)];
-    _userNameLabel.text = nimUser.userInfo.nickName ? nimUser.userInfo.nickName : userId;
     _userNameLabel.textAlignment = NSTextAlignmentCenter;
     [_userNameLabel setTextColor:UIColor.blackColor];
     [self addSubview:_userNameLabel];
     
     _userIdLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, _userNameLabel.bottom, cellWidth, 20)];
-    _userIdLabel.text = [NSString stringWithFormat:@"ID:%@", userId];
+    _userIdLabel.text = [NSString stringWithFormat:@"ID:%@", [User sharedInfo].userInfo.ssid];
     _userIdLabel.textAlignment = NSTextAlignmentCenter;
     _userIdLabel.font = [UIFont systemFontOfSize:15];
     [_userIdLabel setTextColor:UIColor.lightGrayColor];
     [self addSubview:_userIdLabel];
     
     
+    _step = [[UIView alloc] initWithFrame:CGRectMake(0, cellHeight-0.5, cellWidth, 0.5)];
+    _step.backgroundColor = UIColor.lightGrayColor;
+    [self addSubview:_step];
     
-    [self fillPhotos];
+    _socialContainer = [[UIView alloc] initWithFrame:CGRectMake(0, cellHeight-130, cellWidth, 130)];
+    _socialContainer.backgroundColor = UIColor.groupTableViewBackgroundColor;
+    [_socialContainer addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTouchMorePic:)]];
+    [self addSubview:_socialContainer];
+    
+    _socialLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, _socialContainer.width, 20)];
+    _socialLabel.text = @"动态";
+    _socialLabel.font = [UIFont systemFontOfSize:15];
+    [_socialContainer addSubview:_socialLabel];
     
+    _socialPicContainer = [[UIView alloc] initWithFrame:CGRectMake(15, 40, cellWidth-15-50, 76)];
+    [_socialContainer addSubview:_socialPicContainer];
     
+    UIImageView *morePicImg = [[UIImageView alloc] initWithFrame:CGRectMake(cellWidth - 30, 0, 8, 16)];
+    [morePicImg setImage:[UIImage imageNamed:@"设置_03"]];
+    morePicImg.centerY = 40 + (_socialContainer.height - 40) / 2;
+    [_socialContainer addSubview:morePicImg];
     
-    UIView *step = [[UIView alloc] initWithFrame:CGRectMake(0, cellHeight-0.5, cellWidth, 0.5)];
-    step.backgroundColor = UIColor.lightGrayColor;
-    [self addSubview:step];
+    [self fillPhotos];
 }
 
 
 - (void)fillPhotos
 {
+    NSString *userId = [NIMSDK sharedSDK].loginManager.currentAccount;
+    NIMUser *nimUser = [[NIMSDK sharedSDK].userManager userInfo:userId];
+    if(nimUser.userInfo.gender == NIMUserGenderMale || nimUser.userInfo.gender == NIMUserGenderUnknown)
+    {
+        [_genderImg setImage:[UIImage imageNamed:@"我的_07 (3)"]];
+    }
+    else if(nimUser.userInfo.gender == NIMUserGenderFemale)
+    {
+        [_genderImg setImage:[UIImage imageNamed:@"我的_07 (4)"]];
+    }
+    _userNameLabel.text = [[User sharedInfo] getUserName:nimUser];
+
+    
+    
     [self updateBanner];
     
     if(!_photoContainer)
     {
-        _photoContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 300, _cellWidth, 0)];
+        _photoContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 340, _cellWidth, 0)];
         _photoContainer.backgroundColor = UIColor.groupTableViewBackgroundColor;
         [self addSubview:_photoContainer];
     }
     
     float space = 1;
     int columns = 4;
+    int maxPhoto = 7;
     float picWidth = (_cellWidth - (columns - 1) * space) / columns;
     
+    [_thumbArr removeAllObjects];
+    [_picArr removeAllObjects];
     NSMutableArray *photos = [User sharedInfo].userInfo.photeArr;
     for(int i=0; i<photos.count; i++)
     {
+        if(i >= maxPhoto)
+            break;
         float x = (i%columns) * (picWidth+space);
         float y = floorf(i/columns) * (picWidth+space);
         UIImageView *imgView = nil;
         if(i >= _photoContainer.subviews.count)
         {
             imgView = [[UIImageView alloc] init];
+            [imgView setUserInteractionEnabled:YES];
+            [imgView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTouchImage:)]];
             [_photoContainer addSubview:imgView];
         }
         else
@@ -130,12 +185,17 @@
             imgView = [_photoContainer.subviews objectAtIndex:i];
         }
         
+        imgView.tag = i;
         [imgView setHidden:NO];
         [imgView setFrame:CGRectMake(x, y, picWidth, picWidth)];
         
         NSString *thumb = [[photos objectAtIndex:i] objectForKey:@"thumb"];
+        NSString *pic = [[photos objectAtIndex:i] objectForKey:@"pic"];
         NSURL *url = [NSURL URLWithString:thumb];
         [imgView sd_setImageWithURL:url placeholderImage:User.defaultPlaceHolderImage];
+        
+        [_thumbArr addObject:thumb];
+        [_picArr addObject:pic];
     }
     
     int numPhotos = (int)(photos.count);
@@ -144,14 +204,14 @@
         [[_photoContainer.subviews objectAtIndex:j] setHidden:YES];
     }
     
-    _photoContainer.height = floorf(numPhotos/columns) * (picWidth+space) + picWidth;
+    
     
     
     if(!_photoAddBtn)
     {
         _photoAddBtn = [UIButton buttonWithType:UIButtonTypeCustom];
         _photoAddBtn.frame = CGRectMake(0, 0, picWidth, picWidth);
-        _photoAddBtn.backgroundColor = UIColor.whiteColor;
+        _photoAddBtn.backgroundColor = UIColor.groupTableViewBackgroundColor;
         [self addSubview:_photoAddBtn];
         
         
@@ -170,10 +230,83 @@
         [_photoAddBtn addTarget:self action:@selector(onTouchAddPhoto:) forControlEvents:UIControlEventTouchUpInside];
     }
     
+    numPhotos = MIN(maxPhoto, numPhotos);
     float x = (numPhotos%columns) * (picWidth+space);
     float y = floorf(numPhotos/columns) * (picWidth+space) + _photoContainer.top;
     _photoAddBtn.left = x;
     _photoAddBtn.top = y;
+    
+    _photoContainer.height = floorf(numPhotos/columns) * (picWidth+space) + picWidth;
+    _socialContainer.top = _photoContainer.bottom;
+}
+
+- (void)fillSocial:(NSMutableArray *)list{
+    float space = 5;
+    float picWidth = _socialPicContainer.height;
+    
+    [_socialThumbArr removeAllObjects];
+    [_socialPicArr removeAllObjects];
+    
+    int count = 0;
+    BOOL full = NO;
+    for(int i=0; i<list.count; i++)
+    {
+        SocialItemData *item = [list objectAtIndex:i];
+        for(int j=0; j<item.picArr.count; j++)
+        {
+            NSString *thumb = [item.thumbArr objectAtIndex:j];
+            NSString *pic = [item.picArr objectAtIndex:j];
+            
+            float x = count * (picWidth+space);
+            float y = 0;
+            UIImageView *imgView = nil;
+            if(count >= _socialPicContainer.subviews.count)
+            {
+                imgView = [[UIImageView alloc] init];
+                [imgView setUserInteractionEnabled:YES];
+                [imgView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTouchSocialPic:)]];
+                [_socialPicContainer addSubview:imgView];
+            }
+            else
+            {
+                imgView = [_socialPicContainer.subviews objectAtIndex:count];
+            }
+            
+            imgView.tag = count;
+            [imgView setHidden:NO];
+            [imgView setFrame:CGRectMake(x, y, picWidth, picWidth)];
+            
+            NSURL *url = [NSURL URLWithString:thumb];
+            [imgView sd_setImageWithURL:url placeholderImage:User.defaultPlaceHolderImage];
+            
+            [_socialThumbArr addObject:thumb];
+            [_socialPicArr addObject:pic];
+            
+            count++;
+            if(imgView.right + space + picWidth > _socialPicContainer.width)
+            {
+                full = YES;
+                break;
+            }
+        }
+        
+        if(full)
+            break;
+    }
+    
+    for(int j=count; j<_socialPicContainer.subviews.count; j++)
+    {
+        [[_socialPicContainer.subviews objectAtIndex:j] setHidden:YES];
+    }
+}
+
+- (IBAction)onTouchMorePic:(id)sender {
+    NSLog(@"onTouchMorePic");
+    
+    UIStoryboard *board = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
+    SocialTableViewController *vc = [board instantiateViewControllerWithIdentifier:@"TargetSocial"];
+    vc.userInfo = [User sharedInfo].userInfo;
+    [self.viewController.navigationController pushViewController:vc animated:YES];
 }
 
 
@@ -186,7 +319,9 @@
     NIMUser *nimUser = [[NIMSDK sharedSDK].userManager userInfo:userId];
     
     url = nimUser.userInfo.avatarUrl ? [NSURL URLWithString:nimUser.userInfo.avatarUrl] : nil;
-    [_avatarImg nim_setImageWithURL:url placeholderImage:User.defaultUserAvatar];
+    [_avatarImg nim_setImageWithURL:url placeholderImage:User.defaultUserAvatar completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
+        [SVProgressHUD dismiss];
+    }];
 }
 
 - (void)onTouchTopImage:(id)sender{
@@ -226,6 +361,8 @@
 - (void)uploadImage:(UIImage *)image{
     
     __weak typeof(self) wself = self;
+    
+    [SVProgressHUD show];
     [[HttpRequest shared] uploadSocialBanner:image success:^(NSString * _Nullable imgURL) {
         
         [User sharedInfo].userInfo.socialBanner = imgURL;
@@ -233,22 +370,52 @@
         [wself updateBanner];
         
     } failure:^{
-        
+        [SVProgressHUD dismiss];
     }];
     
 }
 
-
+- (void)onTouchImage:(UITapGestureRecognizer *)gestureRecognizer{
+    
+    UIView *viewClicked = [gestureRecognizer view];
+    
+    NSLog(@"show image %ld", (long)viewClicked.tag);
+    
+    int index = (int)viewClicked.tag;
+    ImagePagerViewController *imagePageVC = [[ImagePagerViewController alloc] init];
+//    NSMutableDictionary *photo = [[User sharedInfo].userInfo.photeArr objectAtIndex:index];
+//    NSString *image = [photo objectForKey:@"pic"];
+//    NSString *thumb = [photo objectForKey:@"thumb"];
+//    [imagePageVC setImage:image thumb:thumb];
+    [imagePageVC setImages:_picArr thumbs:_thumbArr startIndex:index];
+    
+    [self.viewController.navigationController pushViewController:imagePageVC animated:YES];
+}
 
 - (void)onTouchAddPhoto:(id)sender{
-    
     AddPhotoViewController *vc = [[AddPhotoViewController alloc] init];
     [self.viewController.navigationController pushViewController:vc animated:YES];
+}
+
+- (void)onTouchSocialPic:(UITapGestureRecognizer *)gestureRecognizer{
+    UIView *viewClicked = [gestureRecognizer view];
+    int index = (int)viewClicked.tag;
     
+    ImagePagerViewController *imagePageVC = [[ImagePagerViewController alloc] init];
+    [imagePageVC setImages:_socialPicArr thumbs:_socialThumbArr startIndex:index];
+    
+    [self.viewController.navigationController pushViewController:imagePageVC animated:YES];
 }
 
 - (void)onTouchAvatar:(id)sender{
-    [User showUserInfo:[NIMSDK sharedSDK].loginManager.currentAccount viewController:self.viewController];
+    NSString *userId = [NIMSDK sharedSDK].loginManager.currentAccount;
+    NIMUser *user = [[NIMSDK sharedSDK].userManager userInfo:userId];
+    if(user && user.userInfo && user.userInfo.avatarUrl)
+    {
+        ImagePagerViewController *vc = [[ImagePagerViewController alloc] init];
+        [vc setImage:user.userInfo.avatarUrl thumb:user.userInfo.thumbAvatarUrl];
+        [self.viewController.navigationController pushViewController:vc animated:YES];
+    }
 }
 
 @end

+ 1 - 0
NIMDemo/NIMDemo/SocialCommentDetailTableViewCell.m

@@ -64,6 +64,7 @@
     _msgTextView = [[UITextView alloc] initWithFrame:CGRectMake(_nickTextView.left, _avatarView.bottom+5, cellWidth - padding - _nickTextView.left, 0)];
     _msgTextView.font = [UIFont systemFontOfSize:15];
     _msgTextView.textContainerInset = UIEdgeInsetsMake(0, 0, 0, 0);
+    _msgTextView.editable = NO;
     [_msgTextView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTouchMsg:)]];
     [self addSubview:_msgTextView];
     

+ 17 - 0
NIMDemo/NIMDemo/SocialDetailTableViewCell.m

@@ -14,6 +14,7 @@
 #import "ImagePagerViewController.h"
 #import "HttpRequest.h"
 #import "SocialDetailViewController.h"
+#import "SocialTableViewController.h"
 
 @interface SocialDetailTableViewCell() <UITextViewDelegate>
 
@@ -27,6 +28,7 @@
 @property (nonatomic, strong) UIButton                      *viewsBtn;
 @property (nonatomic, strong) UIButton                      *likeBtn;
 @property (nonatomic, strong) UIButton                      *commentBtn;
+@property (nonatomic, strong) UIButton                      *deleteBtn;
 @property (nonatomic, strong) UIView                        *likeTitleContainer;
 @property (nonatomic, strong) UILabel                       *likeTitle;
 @property (nonatomic, strong) UIView                        *likeContainer;
@@ -79,6 +81,7 @@
     _msgTextView = [[UITextView alloc] initWithFrame:CGRectMake(padding, _avatarView.bottom+5, cellWidth - padding * 2, 0)];
     _msgTextView.font = [UIFont systemFontOfSize:15];
     _msgTextView.textContainerInset = UIEdgeInsetsMake(0, 0, 0, 0);
+    _msgTextView.editable = NO;
     [self addSubview:_msgTextView];
     
     //image container
@@ -127,6 +130,13 @@
     [_viewsBtn setImage:[UIImage imageNamed:@"朋友圈_03"] forState:UIControlStateNormal];
     //[_actionContainer addSubview:_viewsBtn];
     
+    _deleteBtn = [UIButton buttonWithType:UIButtonTypeCustom];
+    [_deleteBtn setFrame:CGRectMake(_likeBtn.left-3-aBtnWidth, 0, aBtnWidth, aBtnHeight)];
+    _deleteBtn.titleLabel.font = [UIFont systemFontOfSize:14];
+    [_deleteBtn setTitleColor:UIColor.lightGrayColor forState:UIControlStateNormal];
+    [_deleteBtn setTitle:@"删除" forState:UIControlStateNormal];
+    [_deleteBtn addTarget:self action:@selector(onTouchDelete:) forControlEvents:UIControlEventTouchUpInside];
+    [_actionContainer addSubview:_deleteBtn];
     
     //like title
     _likeTitleContainer = [[UIView alloc] initWithFrame:CGRectMake(0, aBtnHeight, cellWidth, 40)];
@@ -260,6 +270,8 @@
     
     [_commentTitle setText:[NSString stringWithFormat:@"全部评论 (%d)", data.comments]];
     
+    _deleteBtn.hidden = ![data.userId isEqualToString:[NIMSDK sharedSDK].loginManager.currentAccount];
+    
     _actionContainer.height = _commentTitleContainer.bottom;
     _cellHeight = _actionContainer.bottom;
 }
@@ -375,4 +387,9 @@
     }];
     
 }
+
+- (void)onTouchDelete:(int)sender{
+    [((SocialDetailViewController *)self.viewController) deleteSocial:_data.socialId];
+}
+
 @end

+ 3 - 0
NIMDemo/NIMDemo/SocialDetailViewController.h

@@ -11,7 +11,10 @@
 
 @interface SocialDetailViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
 
+@property (nonatomic, strong) UITableView               *tableView;
+
 - (void)setSocialData:(SocialItemData *)socialData;
 - (void)beginComment:(NSString *)replyId;
+- (void)deleteSocial:(NSString *)socialId;
 
 @end

+ 20 - 2
NIMDemo/NIMDemo/SocialDetailViewController.m

@@ -13,6 +13,8 @@
 #import "SocialDetailTableViewCell.h"
 #import "SocialCommentDetailTableViewCell.h"
 #import "UIView+NTES.h"
+#import "SVProgressHUD.h"
+#import "UIAlertView+NTESBlock.h"
 
 @interface SocialDetailViewController ()<UIScrollViewDelegate, UITextFieldDelegate>
 
@@ -29,7 +31,6 @@
 @property (nonatomic, strong) UITextField               *commentTextField;
 @property (nonatomic, strong) UIButton                  *commentBtn;
 
-@property (nonatomic, strong) UITableView               *tableView;
 @property (nonatomic, strong) NSString                  *replyId;
 
 @end
@@ -214,7 +215,24 @@
 
 
 
-
+- (void)deleteSocial:(NSString *)socialId{
+    
+    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"是否删除该动态?" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
+    [alert showAlertWithCompletionHandler:^(NSInteger index) {
+        if(index == 1)
+        {
+            [SVProgressHUD show];
+            [[HttpRequest shared] deleteSocialData:socialId success:^(NSString * _Nullable socialId) {
+                [SVProgressHUD dismiss];
+                
+                [self.navigationController popViewControllerAnimated:YES];
+            } failure:^{
+                [SVProgressHUD dismiss];
+            }];
+        }
+    }];
+    
+}
 
 
 

+ 69 - 11
NIMDemo/NIMDemo/SocialPublishViewController.m

@@ -16,16 +16,19 @@
 #import "AFNetworking/AFNetworking.h"
 #import "LocationManager.h"
 #import "HttpRequest.h"
+#import "ImagePagerViewController.h"
 
 @interface SocialPublishViewController ()<UITextViewDelegate, LocationDelegate>
 
 @property (nonatomic, strong) LocationManager       *locationManager;
 @property (nonatomic, assign) double                longitude;
 @property (nonatomic, assign) double                latitude;
+@property (nonatomic, assign) BOOL                  showLoc;
 
 @property (nonatomic, strong) UITextView            *msgTxtView;
 @property (nonatomic, strong) UILabel               *msgReplaceHolder;
 @property (nonatomic, strong) UILabel               *locationLabel;
+@property (nonatomic, strong) UIButton              *locationShowChecker;
 @property (nonatomic, strong) UILabel               *picLabel;
 @property (nonatomic, strong) NSMutableArray        *picArr;
 @property (nonatomic, strong) NSMutableArray        *picDataArr;
@@ -51,7 +54,7 @@ int picColumns = 5;
     _picArr = [[NSMutableArray alloc] init];
     _picDataArr = [[NSMutableArray alloc] init];
     
-    
+    self.showLoc = true;
     
     
     UINavigationItem *navItem = self.navigationItem;
@@ -91,11 +94,27 @@ int picColumns = 5;
     _locationLabel.font = [UIFont systemFontOfSize:15];
     [_locationLabel sizeToFit];
     _locationLabel.top = (30 - _locationLabel.height)/2;
+    if(_locationLabel.width > 200)
+        _locationLabel.width = 200;
     [locationView addSubview:_locationLabel];
     
+    
     locationView.width = _locationLabel.right + 10;
     [self.view addSubview:locationView];
     
+    _locationShowChecker = [[UIButton alloc] initWithFrame:CGRectMake(locationView.right+10, locationView.top, 0, 30)];
+    [_locationShowChecker setTitle:@"不显示位置" forState:UIControlStateNormal];
+    [_locationShowChecker setTitleColor:UIColor.lightGrayColor forState:UIControlStateNormal];
+    _locationShowChecker.font = [UIFont systemFontOfSize:15];
+    [_locationShowChecker setImage:[UIImage imageNamed:@"聊天3_03"] forState:UIControlStateNormal];
+    [_locationShowChecker addTarget:self action:@selector(onShowCheckerChanged) forControlEvents:UIControlEventTouchUpInside];
+    [_locationShowChecker sizeToFit];
+    _locationShowChecker.top = locationView.top + (30 - _locationShowChecker.height)/2;
+    [self.view addSubview:_locationShowChecker];
+    
+    
+    
+    
     
     
     
@@ -115,9 +134,9 @@ int picColumns = 5;
     _picAddBtn = [[UIButton alloc] initWithFrame:CGRectMake(0,  0, picSize, picSize)];
     [_picAddBtn setImage:[UIImage imageNamed:@"朋友圈发布_07"] forState:UIControlStateNormal];
     [_picAddBtn addTarget:self action:@selector(onTouchAddPic:) forControlEvents:UIControlEventTouchUpInside];
-    [_picContainer addSubview:_picAddBtn];
-    
+    [self.view addSubview:_picAddBtn];
     
+    [self layoutPictures];
     
     UIButton *publishBtn = [[UIButton alloc] initWithFrame:CGRectMake(15, _picContainer.bottom+20, self.view.width - 30, 50)];
     [publishBtn setTitle:@"发布" forState:UIControlStateNormal];
@@ -147,6 +166,12 @@ int picColumns = 5;
 - (void)viewWillAppear:(BOOL)animated
 {
     [super viewWillAppear:animated];
+    [self layoutPictures];
+}
+
+- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
+{
+    [self.view endEditing:YES];
 }
 
 
@@ -208,27 +233,38 @@ int picColumns = 5;
     int i = 0;
     for(i=0; i<count; i++){
         startX = (i % picColumns) * (picSize + picPadding);
-        startY = floorf(i / picColumns);
+        startY = floorf(i / picColumns) * (picSize + picPadding);
         
         UIImageView *imgView = nil;
-        if(_picContainer.subviews.count - 1 <= i){
+        if(i >= _picContainer.subviews.count){
             imgView = [[UIImageView alloc] initWithFrame:CGRectMake(startX, startY, picSize, picSize)];
+            [imgView setUserInteractionEnabled:YES];
+            [imgView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTouchImage:)]];
+            [imgView setContentMode:UIViewContentModeScaleAspectFill];
+            [imgView setClipsToBounds:YES];
             [_picContainer addSubview:imgView];
         }
         else{
             imgView = [_picContainer.subviews objectAtIndex:i];
             imgView.left = startX;
             imgView.top = startY;
+            imgView.hidden = NO;
         }
+        imgView.tag = i;
         
         UIImage *img = [_picArr objectAtIndex:i];
         [imgView setImage:img];
     }
+    for(int j=count; j<_picContainer.subviews.count; j++)
+    {
+        UIView *view = [_picContainer.subviews objectAtIndex:j];
+        view.hidden = YES;
+    }
     
     if(count < maxCountPictures)
     {
-        startX = (count % picColumns) * (picSize + picPadding);
-        startY = floorf(count / picColumns);
+        startX = (count % picColumns) * (picSize + picPadding) + _picContainer.left;
+        startY = floorf(count / picColumns) * (picSize + picPadding) + _picContainer.top;
         _picAddBtn.left = startX;
         _picAddBtn.top = startY;
         _picAddBtn.hidden = NO;
@@ -237,6 +273,8 @@ int picColumns = 5;
     {
         _picAddBtn.hidden = YES;
     }
+    
+    [self updatePictureTip];
 }
 
 - (void)onTouchAddPic:(int)sender
@@ -255,6 +293,7 @@ int picColumns = 5;
 - (void)showImagePicker:(UIImagePickerControllerSourceType)type{
     
     __weak typeof(self) weakSelf = self;
+    self.mediaFetcher.limit = maxCountPictures - _picArr.count;
     [self.mediaFetcher fetchPhotoFromLibrary:^(NSArray *images, NSString *path, PHAssetMediaType type) {
         
         int a = 1;
@@ -280,7 +319,13 @@ int picColumns = 5;
     }];
 }
 
-
+- (void)onTouchImage:(UITapGestureRecognizer *)gestureRecognizer{
+    UIView *viewClicked = [gestureRecognizer view];
+    int index = (int)viewClicked.tag;
+    ImagePagerViewController *vc = [[ImagePagerViewController alloc] init];
+    [vc setUIImages:_picArr startIndex:index];
+    [self.navigationController pushViewController:vc animated:YES];
+}
 
 - (void)onTouchPublish:(int)sender{
 
@@ -309,7 +354,7 @@ int picColumns = 5;
     NSString *userId = [NSString stringWithFormat:@"%d", [User sharedInfo].userId];
     NSDictionary *dict = @{@"user_id":userId};
     
-    NSString *urlString = @"http://whosay.dashgame.com/index.php?m=who&c=social&a=upload";
+    NSString *urlString = [NSString stringWithFormat:@"%@%@", [HttpRequest shared].urlRoot, @"index.php?m=who&c=social&a=upload"];
     
     AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
     manager.responseSerializer = [AFJSONResponseSerializer serializer];
@@ -317,7 +362,7 @@ int picColumns = 5;
     
     [manager POST:urlString parameters:dict constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
 
-            NSData *data = UIImageJPEGRepresentation(image, 1);
+            NSData *data = UIImageJPEGRepresentation(image, Image_Compression_Quality);
             [formData appendPartWithFileData:data name:@"upload" fileName:[NSString stringWithFormat:@"image_%d.jpg", _picUploadIndex] mimeType:@"image/jpg"];
         
     } progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
@@ -388,12 +433,16 @@ int picColumns = 5;
     NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
     [parameters setObject:userId forKey:@"id"];
     [parameters setObject:local forKey:@"local"];
+    [parameters setObject:(_showLoc ? @"1" : @"0") forKey:@"show_local"];
+    [parameters setObject:user.province forKey:@"province"];
+    [parameters setObject:user.city forKey:@"city"];
+    [parameters setObject:user.district forKey:@"district"];
     [parameters setObject:msg forKey:@"msg"];
     [parameters setObject:_picDataArr forKey:@"pic"];
     [parameters setObject:[NSString stringWithFormat:@"%F", _longitude] forKey:@"longitude"];
     [parameters setObject:[NSString stringWithFormat:@"%F", _latitude] forKey:@"latitude"];
     
-    NSString *urlString = @"http://whosay.dashgame.com/index.php?m=who&c=social&a=publish";
+    NSString *urlString = [NSString stringWithFormat:@"%@%@", [HttpRequest shared].urlRoot, @"index.php?m=who&c=social&a=publish"];
     //请求的managers
     AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
     manager.responseSerializer = [AFJSONResponseSerializer new];
@@ -428,5 +477,14 @@ int picColumns = 5;
         [self.view makeToast:@"发布失败" duration:2.0 position:CSToastPositionCenter];
     }];
 }
+
+
+- (void)onShowCheckerChanged{
+    _showLoc = !_showLoc;
+    if(_showLoc)
+        [_locationShowChecker setImage:[UIImage imageNamed:@"聊天3_03"] forState:UIControlStateNormal];
+    else
+        [_locationShowChecker setImage:[UIImage imageNamed:@"聊天3_05"] forState:UIControlStateNormal];
+}
      
 @end

+ 28 - 6
NIMDemo/NIMDemo/SocialTableViewCell.m

@@ -30,6 +30,7 @@
 @property (nonatomic, strong) UIButton                  *viewsBtn;
 @property (nonatomic, strong) UIButton                  *likeBtn;
 @property (nonatomic, strong) UIButton                  *commentBtn;
+@property (nonatomic, strong) UIButton                  *deleteBtn;
 
 @property (nonatomic, strong) UIView                    *likesContainer;
 @property (nonatomic, strong) UITextView                *likeUserNames;
@@ -78,7 +79,7 @@
     _nickTextView.textAlignment = NSTextAlignmentLeft;
     [self addSubview:_nickTextView];
     
-    _msgTxtView = [[UITextView alloc] initWithFrame:CGRectMake(contentX-5, 35, cellWidth - 10 - contentX, 100)];
+    _msgTxtView = [[UITextView alloc] initWithFrame:CGRectMake(contentX-5, 35, cellWidth - 10 - contentX, 30)];
     [_msgTxtView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(showAllComments:)]];
     _msgTxtView.font = [UIFont systemFontOfSize:15];
     _msgTxtView.editable = NO;
@@ -103,7 +104,7 @@
     _commentBtn.titleLabel.font = [UIFont systemFontOfSize:14];
     [_commentBtn setTitleColor:UIColor.lightGrayColor forState:UIControlStateNormal];
     [_commentBtn setImage:[UIImage imageNamed:@"朋友圈_09"] forState:UIControlStateNormal];
-    [_commentBtn setTitle:@"评论" forState:UIControlStateNormal];
+    //[_commentBtn setTitle:@"评论" forState:UIControlStateNormal];
     [_commentBtn addTarget:self action:@selector(onTouchComment:) forControlEvents:UIControlEventTouchUpInside];
     [_actionContainer addSubview:_commentBtn];
     
@@ -123,6 +124,13 @@
     [_viewsBtn setImage:[UIImage imageNamed:@"朋友圈_03"] forState:UIControlStateNormal];
     //[_actionContainer addSubview:_viewsBtn];
     
+    _deleteBtn = [UIButton buttonWithType:UIButtonTypeCustom];
+    [_deleteBtn setFrame:CGRectMake(_likeBtn.left-3-aBtnWidth, 0, aBtnWidth, _actionContainer.height)];
+    _deleteBtn.titleLabel.font = [UIFont systemFontOfSize:14];
+    [_deleteBtn setTitle:@"删除" forState:UIControlStateNormal];
+    [_deleteBtn setTitleColor:UIColor.lightGrayColor forState:UIControlStateNormal];
+    [_deleteBtn addTarget:self action:@selector(onTouchDelete:) forControlEvents:UIControlEventTouchUpInside];
+    [_actionContainer addSubview:_deleteBtn];
     
     _likesContainer = [[UIView alloc] initWithFrame:CGRectMake(contentX, 0, cellWidth - contentX - 10, 30)];
     [_likesContainer setBackgroundColor:UIColorFromRGB(0xeeeeee)];
@@ -168,14 +176,14 @@
     
     _data = data;
     
-    [_avatarImg nim_setImageWithURL:nil placeholderImage:[UIImage imageNamed:@"avatar_team"]];
+    [_avatarImg nim_setImageWithURL:nil placeholderImage:[User defaultUserAvatar]];
     _avatarImg.tag = [data.userId intValue];
 
     NIMUser *user = [[NIMSDK sharedSDK].userManager userInfo:data.userId];
     if(user)
     {
         NSURL *url = user.userInfo.avatarUrl ? [NSURL URLWithString:user.userInfo.avatarUrl] : nil;
-        [_avatarImg nim_setImageWithURL:url placeholderImage:[UIImage imageNamed:@"avatar_user2"]];
+        [_avatarImg nim_setImageWithURL:url placeholderImage:[User defaultUserAvatar]];
 
         
         NSString *nick = user && user.userInfo.nickName ? user.userInfo.nickName : data.userId;
@@ -192,7 +200,14 @@
     _msgTxtView.text = data.msg;
     _msgTxtView.height = _msgTxtView.contentSize.height;
     
-    _picContainer.top = _msgTxtView.bottom + 5;
+    if(data.msg.length > 0)
+    {
+        _picContainer.top = _msgTxtView.bottom + 5;
+    }
+    else
+    {
+        _picContainer.top = _msgTxtView.top;
+    }
     
     CGFloat picPadding = 5;
     int columns = 3;
@@ -250,6 +265,7 @@
     else
         [_likeBtn setImage:[UIImage imageNamed:@"朋友圈_06"] forState:UIControlStateNormal];
     
+    _deleteBtn.hidden = ![_data.userId isEqualToString:[NIMSDK sharedSDK].loginManager.currentAccount];
     
     [self setUpLikes];
     [self setUpComments];
@@ -497,6 +513,7 @@
     if(_data.liked > 0)
         return;
     
+    __weak typeof(self) wself = self;
     [[HttpRequest shared] socialLike:_data.socialId success:^(NSString * _Nullable socialId, int currentLikes, NSMutableArray *likeList) {
         
         if([_data.socialId isEqualToString:socialId])
@@ -504,7 +521,9 @@
             _data.liked = 1;
             _data.likes = currentLikes;
             _data.likeArr = likeList;
-            [self setData:_data];
+            [wself setData:_data];
+            
+            [((SocialTableViewController *)self.viewController).tableView reloadData];
         }
         
     } failure:^{
@@ -521,6 +540,9 @@
     [((SocialTableViewController *)self.viewController) inputComment:_data.socialId targetId:userId];
 }
 
+- (void)onTouchDelete:(int)sender{
+    [((SocialTableViewController *)self.viewController) deleteSocial:_data.socialId];
+}
 
 
 

+ 5 - 0
NIMDemo/NIMDemo/SocialTableViewController.h

@@ -7,9 +7,14 @@
 //
 
 #import <UIKit/UIKit.h>
+#import "User.h"
 
 @interface SocialTableViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
 
+@property (nonatomic, strong) UITableView       *tableView;
+@property (nonatomic, strong) UserInfo          *userInfo;
+
 - (void)inputComment:(NSString *)socialId targetId:(NSString *)targetId;
+- (void)deleteSocial:(NSString *)socialId;
 
 @end

+ 62 - 11
NIMDemo/NIMDemo/SocialTableViewController.m

@@ -13,6 +13,8 @@
 #import "HttpRequest.h"
 #import "UIView+NTES.h"
 #import "User.h"
+#import "SVProgressHUD.h"
+#import "UIAlertView+NTESBlock.h"
 
 @interface SocialTableViewController () <UIScrollViewDelegate, UITextFieldDelegate>
 
@@ -27,8 +29,6 @@
 @property (nonatomic, strong) NSString          *commentSocialId;
 @property (nonatomic, strong) NSString          *commentTargetId;
 
-@property (nonatomic, strong) UITableView               *tableView;
-
 @end
 
 @implementation SocialTableViewController
@@ -106,6 +106,11 @@
         [self reset];
     }
     
+    
+    if(_userInfo)
+       [self.navigationItem setTitle:@"动态"];
+    
+    [self.tableView reloadData];
 }
 
 - (UITableView *)tableView
@@ -115,6 +120,8 @@
     }
     if (!_tableView) {
         float startY = [[UIApplication sharedApplication] statusBarFrame].size.height + self.navigationController.navigationBar.frame.size.height;
+        if(_userInfo)
+            startY = 0;
         _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.width, self.view.height) style:UITableViewStylePlain];
         _tableView.contentInset = UIEdgeInsetsMake(startY, 0, 0, 0);
         _tableView.backgroundColor  = [UIColor clearColor];
@@ -140,24 +147,33 @@
     _isFetching = YES;
     
     NSString *lastId = nil;
-    if(self.dataList && self.dataList.count){
-        NSObject *lastData = [self.dataList lastObject];
+    if(self.dataList && self.dataList.count > 1){
+        NSObject *lastData = [self.dataList objectAtIndex:1];
         if([lastData isKindOfClass:[SocialItemData class]])
             lastId = ((SocialItemData *)lastData).socialId;
     }
         
-    
-    [[HttpRequest shared] getSocialDataList:lastId success:^(NSMutableArray *dataList) {
+    [SVProgressHUD show];
+    NSString *targetId = _userInfo ? _userInfo.userId : @"";
+    [[HttpRequest shared] getSocialDataList:lastId targetId:targetId success:^(NSMutableArray *dataList) {
+        [SVProgressHUD dismiss];
         if(!self.dataList)
+        {
             self.dataList = dataList;
+        }
         else
-            [self.dataList addObjectsFromArray:dataList];
+        {
+            NSRange range = NSMakeRange(1, dataList.count);
+            NSIndexSet *set = [NSIndexSet indexSetWithIndexesInRange:range];
+            [self.dataList insertObjects:dataList atIndexes:set];
+        }
         
         [self.tableView reloadData];
         
         _isFetching = NO;
     } failure:^{
         _isFetching = NO;
+        [SVProgressHUD dismiss];
     }];
 }
 
@@ -200,10 +216,12 @@
         if(!cell)
         {
             cell = [[SocialTopTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
-            [cell initSize:self.view.frame.size.width cellHeight:160];
+            [cell initSize:self.view.frame.size.width cellHeight:240];
         }
-        
-        [cell setData:[User sharedInfo]];
+        if(_userInfo)
+            [cell setData:_userInfo];
+        else
+            [cell setData:[User sharedInfo].userInfo];
         baseCell = cell;
     }
     return baseCell;
@@ -221,7 +239,7 @@
     {
         return ((SocialItemData *)data).cellHeight;
     }
-    return 160;
+    return 240;
 }
 
 /*
@@ -306,6 +324,39 @@
 }
 
 
+- (void)deleteSocial:(NSString *)socialId{
+    
+    __weak typeof(self) wself = self;
+    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"是否删除该动态?" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
+    [alert showAlertWithCompletionHandler:^(NSInteger index) {
+        if(index == 1)
+        {
+            [SVProgressHUD show];
+            [[HttpRequest shared] deleteSocialData:socialId success:^(NSString * _Nullable socialId) {
+                [SVProgressHUD dismiss];
+                
+                for(int i=0; i<wself.dataList.count; i++)
+                {
+                    if([[wself.dataList objectAtIndex:i] isKindOfClass:[SocialItemData class]])
+                    {
+                        SocialItemData *item = [wself.dataList objectAtIndex:i];
+                        if([item.socialId isEqualToString:socialId])
+                        {
+                            [wself.dataList removeObject:item];
+                            break;
+                        }
+                    }
+                }
+                
+                [wself.tableView reloadData];
+            } failure:^{
+                [SVProgressHUD dismiss];
+            }];
+        }
+    }];
+    
+}
+
 
 - (void)onTouchComment:(id)sender{
     [self sendComment:_commentTextField.text];

+ 1 - 1
NIMDemo/NIMDemo/SocialTopTableViewCell.h

@@ -12,6 +12,6 @@
 @interface SocialTopTableViewCell : UITableViewCell
 
 - (void)initSize:(CGFloat)cellWidth cellHeight:(CGFloat)cellHeight;
-- (void)setData:(User *)user;
+- (void)setData:(UserInfo *)userInfo;
 
 @end

+ 38 - 10
NIMDemo/NIMDemo/SocialTopTableViewCell.m

@@ -13,13 +13,15 @@
 #import "User.h"
 #import "HttpRequest.h"
 #import "UIActionSheet+NTESBlock.h"
-
+#import "SVProgressHUD.h"
 
 @interface SocialTopTableViewCell()<UINavigationControllerDelegate, UIImagePickerControllerDelegate>
 
 @property (nonatomic, strong) UIImageView           *imgBg;
+@property (nonatomic, strong) UILabel               *imgLabel;
 @property (nonatomic, strong) NIMAvatarImageView    *avatarImg;
 @property (nonatomic, strong) UILabel               *nameLabel;
+@property (nonatomic, strong) UserInfo              *userInfo;
 
 @end
 
@@ -43,6 +45,17 @@
     [_imgBg addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTouchBanner:)]];
     [self addSubview:_imgBg];
     
+    _imgLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, cellWidth, 20)];
+    _imgLabel.text = @"轻触换背景";
+    _imgLabel.centerY = _imgBg.centerY;
+    _imgLabel.font = [UIFont systemFontOfSize:15];
+    _imgLabel.textColor = UIColor.whiteColor;
+    _imgLabel.shadowColor = UIColor.grayColor;
+    _imgLabel.shadowOffset = CGSizeMake(1, 1);
+    _imgLabel.textAlignment = NSTextAlignmentCenter;
+    [self addSubview:_imgLabel];
+
+    
     
     _avatarImg = [[NIMAvatarImageView alloc] initWithFrame:CGRectMake(15, cellHeight - 70, 60, 60)];
     [_avatarImg nim_setImageWithURL:nil placeholderImage:[UIImage imageNamed:@"avatar_user2"]];
@@ -54,19 +67,31 @@
     [self addSubview:_nameLabel];
 }
 
-- (void)setData:(User *)user{
-    
-    NSString *userId = [NIMSDK sharedSDK].loginManager.currentAccount;
-    NIMUser *nimUser = [[NIMSDK sharedSDK].userManager userInfo:userId];
+- (void)setData:(UserInfo *)userInfo{
+    _userInfo = userInfo;
+    NIMUser *nimUser = [[NIMSDK sharedSDK].userManager userInfo:_userInfo.userId];
     NSURL *url = nimUser && nimUser.userInfo.avatarUrl ? [NSURL URLWithString:nimUser.userInfo.avatarUrl] : nil;
     [_avatarImg nim_setImageWithURL:url placeholderImage:[UIImage imageNamed:@"avatar_user2"]];
     
-    _nameLabel.text = nimUser && nimUser.userInfo.nickName ? nimUser.userInfo.nickName : userId;
+    _nameLabel.text = [[User sharedInfo] getUserName:nimUser];
+    
+    if([userInfo.userId isEqualToString:[NIMSDK sharedSDK].loginManager.currentAccount])
+    {
+        _imgLabel.hidden = NO;
+    }
+    else
+    {
+        _imgLabel.hidden = YES;
+    }
     
     [self updateBanner];
 }
 
 - (void)onTouchBanner:(UITapGestureRecognizer *)gestureRecognizer{
+    
+    if(![_userInfo.userId isEqualToString:[NIMSDK sharedSDK].loginManager.currentAccount])
+        return;
+    
     UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"设置封面" delegate:nil cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"从相册", nil];
     [sheet showInView:self.viewController.view completionHandler:^(NSInteger index) {
         switch (index) {
@@ -101,6 +126,7 @@
 - (void)uploadImage:(UIImage *)image{
     
     __weak typeof(self) wself = self;
+    [SVProgressHUD show];
     [[HttpRequest shared] uploadSocialBanner:image success:^(NSString * _Nullable imgURL) {
         
         [User sharedInfo].userInfo.socialBanner = imgURL;
@@ -108,19 +134,21 @@
         [wself updateBanner];
         
     } failure:^{
-        
+        [SVProgressHUD dismiss];
     }];
     
 }
 
 - (void)updateBanner{
-    NSString *imgURL = [User sharedInfo].userInfo.socialBanner;
+    NSString *imgURL = _userInfo.socialBanner;
     NSURL *url = imgURL && imgURL.length > 0 ? [NSURL URLWithString:imgURL] : nil;
-    [self.imgBg sd_setImageWithURL:url placeholderImage:User.defaultSocialBanner];
+    [self.imgBg sd_setImageWithURL:url placeholderImage:User.defaultSocialBanner completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
+        [SVProgressHUD dismiss];
+    }];
 }
 
 - (void)onTouchAvatar:(id)sender{
-    [User showUserInfo:[NIMSDK sharedSDK].loginManager.currentAccount viewController:self.viewController];
+    [User showUserInfo:_userInfo.userId viewController:self.viewController];
 }
 
 @end

+ 4 - 6
NIMDemo/NIMDemo/Supporting Files/Info.plist

@@ -21,7 +21,7 @@
 	<key>CFBundlePackageType</key>
 	<string>APPL</string>
 	<key>CFBundleShortVersionString</key>
-	<string>1.0.0</string>
+	<string>1.0.2</string>
 	<key>CFBundleSignature</key>
 	<string>????</string>
 	<key>CFBundleURLTypes</key>
@@ -36,7 +36,7 @@
 		</dict>
 	</array>
 	<key>CFBundleVersion</key>
-	<string>1</string>
+	<string>4</string>
 	<key>LSApplicationCategoryType</key>
 	<string></string>
 	<key>LSApplicationQueriesSchemes</key>
@@ -57,7 +57,7 @@
 	<key>NSContactsUsageDescription</key>
 	<string>谁说想使用您的通讯录</string>
 	<key>NSLocationAlwaysUsageDescription</key>
-	<string>谁说想使用您的地理位置信息</string>
+	<string>谁说想使用您的地理位置信息,使你想要展示所在位置时更加便捷</string>
 	<key>NSLocationWhenInUseDescription</key>
 	<string>谁说想使用您的地理位置信息</string>
 	<key>NSMicrophoneUsageDescription</key>
@@ -66,10 +66,8 @@
 	<string>谁说想使用您的相册</string>
 	<key>UIBackgroundModes</key>
 	<array>
-		<string>audio</string>
+		<string>remote-notification</string>
 	</array>
-	<key>UIFileSharingEnabled</key>
-	<true/>
 	<key>UILaunchStoryboardName</key>
 	<string>LaunchScreen</string>
 	<key>UIMainStoryboardFile</key>

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor